python löschen - Sortieren Sie eine Liste von Tupeln nach dem 2.Element(Integer-Wert)



zahlen deutsch (9)

>>> from operator import itemgetter
>>> data = [('abc', 121),('abc', 231),('abc', 148), ('abc',221)]
>>> sorted(data,key=itemgetter(1))
[('abc', 121), ('abc', 148), ('abc', 221), ('abc', 231)]

IMO mit itemgetter ist in diesem Fall besser lesbar als die Lösung von @cheeken. Es ist auch schneller, da fast die gesamte Berechnung auf der c Seite (kein Wortspiel beabsichtigt) statt durch die Verwendung von lambda .

>python -m timeit -s "from operator import itemgetter; data = [('abc', 121),('abc', 231),('abc', 148), ('abc',221)]" "sorted(data,key=itemgetter(1))"
1000000 loops, best of 3: 1.22 usec per loop

>python -m timeit -s "data = [('abc', 121),('abc', 231),('abc', 148), ('abc',221)]" "sorted(data,key=lambda x: x[1])"
1000000 loops, best of 3: 1.4 usec per loop

Diese Frage hat hier bereits eine Antwort:

Ich habe eine Liste von Tupeln, die ungefähr so ​​aussieht:

[('abc', 121),('abc', 231),('abc', 148), ('abc',221)]

Ich möchte diese Liste in aufsteigender Reihenfolge nach dem ganzzahligen Wert innerhalb der Tupel sortieren. Ist es möglich?


Aus dem Python-Wiki:

>>> from operator import itemgetter, attrgetter    
>>> sorted(student_tuples, key=itemgetter(2))
[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]    
>>> sorted(student_objects, key=attrgetter('age'))
[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]

Für Python 2.7+ funktioniert das, was die akzeptierte Antwort etwas lesbarer macht:

sorted([('abc', 121),('abc', 231),('abc', 148), ('abc',221)], key=lambda (k, val): val)

Verwenden Sie das key keyword mit sorted() .

sorted([('abc', 121),('abc', 231),('abc', 148), ('abc',221)], key=lambda x: x[1])

key sollte eine Funktion sein, die angibt, wie das vergleichbare Element aus Ihrer Datenstruktur abgerufen wird. In Ihrem Fall ist es das zweite Element des Tupels, also greifen wir auf [1] .

Zur Optimierung siehe die Antwort von itemgetter(1) mit itemgetter(1) , die im Wesentlichen eine schnellere Version von lambda x: x[1] .


Die Tatsache, dass die Sortierwerte im OP Ganzzahlen sind, ist für die Frage per se nicht relevant. Mit anderen Worten, die angenommene Antwort würde funktionieren, wenn der Sortierwert Text wäre. Ich führe dies auch darauf hin, dass die Sortierung während der Sortierung geändert werden kann (zB um Groß- und Kleinschreibung zu berücksichtigen).

>>> sorted([(121, 'abc'), (231, 'def'), (148, 'ABC'), (221, 'DEF')], key=lambda x: x[1])
[(148, 'ABC'), (221, 'DEF'), (121, 'abc'), (231, 'def')]
>>> sorted([(121, 'abc'), (231, 'def'), (148, 'ABC'), (221, 'DEF')], key=lambda x: str.lower(x[1]))
[(121, 'abc'), (148, 'ABC'), (231, 'def'), (221, 'DEF')]

Verwenden Sie für eine direkte Sortierung

foo = [(list of tuples)]
foo.sort(key=lambda x:x[0]) #To sort by first element of the tuple

Definieren Sie für eine Lambda-Vermeidungsmethode zuerst Ihre eigene Funktion:

def MyFn(a):
    return a[1]

dann:

sorted([('abc', 121),('abc', 231),('abc', 148), ('abc',221)], key=MyFn)

Als Python-Neophyt wollte ich nur erwähnen, dass wenn die Daten tatsächlich so aussehen:

data = [('abc', 121),('abc', 231),('abc', 148), ('abc',221)]

Dann sorted() automatisch nach dem zweiten Element im Tupel, da die ersten Elemente alle identisch sind.


Kritik anderer Antworten hier:

Keine dieser Antworten sind gleich große Stücke, sie hinterlassen am Ende alle einen kleinen Brocken, also sind sie nicht vollständig ausgeglichen. Wenn Sie diese Funktionen nutzen, um Arbeit zu verteilen, haben Sie die Aussicht auf eine wahrscheinliche Fertigstellung weit vor den anderen eingebaut, so dass es nichts tun würde, während die anderen weiter hart arbeiten.

Zum Beispiel endet die aktuelle Top-Antwort mit:

[60, 61, 62, 63, 64, 65, 66, 67, 68, 69],
[70, 71, 72, 73, 74]]

Ich hasse diesen Typen am Ende!

Andere, wie die list(grouper(3, xrange(7))) , und der chunk(xrange(7), 3) kehren beide zurück: [(0, 1, 2), (3, 4, 5), (6, None, None)] . Die None sind nur Polster, und ziemlich unelegant meiner Meinung nach. Sie sind nicht gleichmäßig die iterables Chunking.

Warum können wir diese nicht besser teilen?

Meine Lösung (en)

Hier ist eine ausgewogene Lösung, die aus einer Funktion stammt, die ich in der Produktion verwendet habe (Hinweis in Python 3, um xrange durch range zu ersetzen):

def baskets_from(items, maxbaskets=25):
    baskets = [[] for _ in xrange(maxbaskets)] # in Python 3 use range
    for i, item in enumerate(items):
        baskets[i % maxbaskets].append(item)
    return filter(None, baskets) 

Und ich habe einen Generator erstellt, der dasselbe tut, wenn Sie ihn in eine Liste schreiben:

def iter_baskets_from(items, maxbaskets=3):
    '''generates evenly balanced baskets from indexable iterable'''
    item_count = len(items)
    baskets = min(item_count, maxbaskets)
    for x_i in xrange(baskets):
        yield [items[y_i] for y_i in xrange(x_i, item_count, baskets)]

Und schließlich, da ich sehe, dass alle oben genannten Funktionen Elemente in einer zusammenhängenden Reihenfolge (wie sie gegeben wurden) zurückgeben:

def iter_baskets_contiguous(items, maxbaskets=3, item_count=None):
    '''
    generates balanced baskets from iterable, contiguous contents
    provide item_count if providing a iterator that doesn't support len()
    '''
    item_count = item_count or len(items)
    baskets = min(item_count, maxbaskets)
    items = iter(items)
    floor = item_count // baskets 
    ceiling = floor + 1
    stepdown = item_count % baskets
    for x_i in xrange(baskets):
        length = ceiling if x_i < stepdown else floor
        yield [items.next() for _ in xrange(length)]

Ausgabe

Um sie zu testen:

print(baskets_from(xrange(6), 8))
print(list(iter_baskets_from(xrange(6), 8)))
print(list(iter_baskets_contiguous(xrange(6), 8)))
print(baskets_from(xrange(22), 8))
print(list(iter_baskets_from(xrange(22), 8)))
print(list(iter_baskets_contiguous(xrange(22), 8)))
print(baskets_from('ABCDEFG', 3))
print(list(iter_baskets_from('ABCDEFG', 3)))
print(list(iter_baskets_contiguous('ABCDEFG', 3)))
print(baskets_from(xrange(26), 5))
print(list(iter_baskets_from(xrange(26), 5)))
print(list(iter_baskets_contiguous(xrange(26), 5)))

Welches druckt aus:

[[0], [1], [2], [3], [4], [5]]
[[0], [1], [2], [3], [4], [5]]
[[0], [1], [2], [3], [4], [5]]
[[0, 8, 16], [1, 9, 17], [2, 10, 18], [3, 11, 19], [4, 12, 20], [5, 13, 21], [6, 14], [7, 15]]
[[0, 8, 16], [1, 9, 17], [2, 10, 18], [3, 11, 19], [4, 12, 20], [5, 13, 21], [6, 14], [7, 15]]
[[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10, 11], [12, 13, 14], [15, 16, 17], [18, 19], [20, 21]]
[['A', 'D', 'G'], ['B', 'E'], ['C', 'F']]
[['A', 'D', 'G'], ['B', 'E'], ['C', 'F']]
[['A', 'B', 'C'], ['D', 'E'], ['F', 'G']]
[[0, 5, 10, 15, 20, 25], [1, 6, 11, 16, 21], [2, 7, 12, 17, 22], [3, 8, 13, 18, 23], [4, 9, 14, 19, 24]]
[[0, 5, 10, 15, 20, 25], [1, 6, 11, 16, 21], [2, 7, 12, 17, 22], [3, 8, 13, 18, 23], [4, 9, 14, 19, 24]]
[[0, 1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 13, 14, 15], [16, 17, 18, 19, 20], [21, 22, 23, 24, 25]]

Beachten Sie, dass der zusammenhängende Generator Chunks in den gleichen Längenmustern wie die anderen beiden bereitstellt, aber die Elemente sind alle in der richtigen Reihenfolge und sie sind so gleichmäßig aufgeteilt, dass eine Liste von diskreten Elementen geteilt werden kann.





python list tuples