猿问

Python:根据条件拆分列表?

Python:根据条件拆分列表?

anims  = [f for f in files if f[2].lower() not in IMAGE_TYPES]

从美学和性能角度来看,根据条件将项目列表拆分为多个列表的最佳方法是什么?相当于:


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

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

有什么更优雅的方法吗?


更新:下面是实际的用例,以更好地解释我想要做的事情:


# 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]


慕勒3428872
浏览 2904回答 3
3回答

慕慕森

good = [x for x in mylist if x in goodvals]bad  = [x for x in mylist if x not in goodvals]有什么更优雅的方法吗?这段代码可读性很好,而且非常清晰!# 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]再说一次,这是很好!使用集合可能会有轻微的性能改进,但这是一个微小的差别,我发现列表理解要容易得多,您不必担心顺序被弄乱了,重复的内容也会被删除等等。实际上,我可能会“倒退”另一步,只需使用一个简单的for循环:images, anims = [], []for f in files:     if f.lower() in IMAGE_TYPES:         images.append(f)     else:         anims.append(f)清单-理解或使用set()没有问题,除非您需要添加其他检查或其他逻辑-假设您想删除所有0字节的jpeg,您只需添加以下内容。if f[1] == 0:     continue

汪汪一只猫

good, bad = [], []for x in mylist:     (bad, good)[x in goodvals].append(x)

UYOU

以下是懒惰迭代器方法:from itertools import teedef split_on_condition(seq, condition):     l1, l2 = tee((condition(item), item) for item in seq)     return (i for p, i in l1 if p), (i for p, i in l2 if not p)它每项计算一次条件,并返回两个生成器,首先从条件为真的序列中产生值,另一个生成条件为false的序列。因为它很懒,所以您可以在任何迭代器上使用它,甚至是无限迭代器:from itertools import count, islicedef is_prime(n):     return n > 1 and all(n % i for i in xrange(2, n))primes, not_primes = split_on_condition(count(), is_prime)     print("First 10 primes", list(islice(primes, 10)))print("First 10 non-primes", list(islice(not_primes, 10)))通常情况下,非延迟列表返回方法更好:def split_on_condition(seq, condition):     a, b = [], []     for item in seq:         (a if condition(item) else b).append(item)     return a, b编辑:对于通过某些键将项拆分为不同列表的更具体的用法,下面是一个通用函数:DROP_VALUE = lambda _:_def split_by_key(seq, resultmapping, keyfunc, default=DROP_VALUE):     """Split a sequence into lists based on a key function.         seq - input sequence         resultmapping - a dictionary that maps from target lists to keys that go to that list         keyfunc - function to calculate the key of an input value         default - the target where items that don't have a corresponding key go, by default they are dropped     """     result_lists = dict((key, []) for key in resultmapping)     appenders = dict((key, result_lists[target].append) for target, keys in resultmapping.items() for key in keys)     if default is not DROP_VALUE:         result_lists.setdefault(default, [])         default_action = result_lists[default].append    else:         default_action = DROP_VALUE    for item in seq:         appenders.get(keyfunc(item), default_action)(item)     return result_lists用法:def file_extension(f):     return f[2].lower()split_files = split_by_key(files, {'images': IMAGE_TYPES}, keyfunc=file_extension, default='anims')     print split_files['images']print split_files['anims']
随时随地看视频慕课网APP

相关分类

Python
我要回答