397 Stimmen

Wie kann man eine Liste anhand einer Bedingung aufteilen?

Was ist der beste Weg, sowohl ästhetisch als auch von der Leistung her, um eine Liste von Elementen in mehrere Listen auf der Grundlage einer Bedingung aufzuteilen? Das Äquivalent von:

good = [x for x in mylist if x in goodvals]
bad  = [x for x in mylist if x not in goodvals]

Gibt es eine elegantere Möglichkeit, dies zu tun?

Hier ist der eigentliche Anwendungsfall, um besser zu erklären, was ich zu tun versuche:

# files looks like: [ ('file1.jpg', 33L, '.jpg'), ('file2.avi', 999L, '.avi'), ... ]
IMAGE_TYPES = ('.jpg','.jpeg','.gif','.bmp','.png')
images = [f for f in files if f[2].lower() in IMAGE_TYPES]
anims  = [f for f in files if f[2].lower() not in IMAGE_TYPES]

1voto

David Punkte 1005

Wenn die Liste aus Gruppen und intermittierenden Trennzeichen besteht, können Sie diese verwenden:

def split(items, p):
    groups = [[]]
    for i in items:
        if p(i):
            groups.append([])
        groups[-1].append(i)
    return groups

Verwendung:

split(range(1,11), lambda x: x % 3 == 0)
# gives [[1, 2], [3, 4, 5], [6, 7, 8], [9, 10]]

1voto

Shay Punkte 1098

Eine weitere Antwort, kurz, aber "böse" (für die Nebenwirkungen des Listenverständnisses).

digits = list(range(10))
odd = [x.pop(i) for i, x in enumerate(digits) if x % 2]

>>> odd
[1, 3, 5, 7, 9]

>>> digits
[0, 2, 4, 6, 8]

1voto

scp10011 Punkte 138

Boolesche Logik verwenden, um Daten zwei Arrays zuzuweisen

>>> images, anims = [[i for i in files if t ^ (i[2].lower() in IMAGE_TYPES) ] for t in (0, 1)]
>>> images
[('file1.jpg', 33, '.jpg')]
>>> anims
[('file2.avi', 999, '.avi')]

1voto

doctorzeb8 Punkte 11

Lösung

from itertools import tee

def unpack_args(fn):
    return lambda t: fn(*t)

def separate(fn, lx):
    return map(
        unpack_args(
            lambda i, ly: filter(
                lambda el: bool(i) == fn(el),
                ly)),
        enumerate(tee(lx, 2)))

Test

[even, odd] = separate(
    lambda x: bool(x % 2),
    [1, 2, 3, 4, 5])
print(list(even) == [2, 4])
print(list(odd) == [1, 3, 5])

0voto

kiran Punkte 13

Ich bin mir nicht sicher, ob dies ein guter Ansatz ist, aber es kann auch auf diese Weise geschehen

IMAGE_TYPES = ('.jpg','.jpeg','.gif','.bmp','.png')
files = [ ('file1.jpg', 33L, '.jpg'), ('file2.avi', 999L, '.avi')]
images, anims = reduce(lambda (i, a), f: (i + [f], a) if f[2] in IMAGE_TYPES else (i, a + [f]), files, ([], []))

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X