flat_list = [item for sublist in l for item in sublist]
这意味着:
flat_list = []for sublist in l:for item in sublist:flat_list.append(item)
比目前发布的快捷方式更快。(l是要展平的列表。)
下面是对应的函数:
def flatten(l):return [item for sublist in l for item in sublist]
作为证据,您可以使用标准库中的timeit模块:
$ python -mtimeit -s'l=[[1,2,3],[4,5,6], [7], [8,9]]*99' '[item for sublist in l for item in sublist]'10000 loops, best of 3: 143 usec per loop$ python -mtimeit -s'l=[[1,2,3],[4,5,6], [7], [8,9]]*99' 'sum(l, [])'1000 loops, best of 3: 969 usec per loop$ python -mtimeit -s'l=[[1,2,3],[4,5,6], [7], [8,9]]*99' 'reduce(lambda x,y: x+y,l)'1000 loops, best of 3: 1.1 msec per loop
这种方法可以说比[item for sublist in l for item in sublist]更具可读性,并且似乎也更快:
$ python3 -mtimeit -s'l=[[1,2,3],[4,5,6], [7], [8,9]]*99;import itertools' 'list(itertools.chain.from_iterable(l))'20000 loops, best of 5: 10.8 usec per loop$ python3 -mtimeit -s'l=[[1,2,3],[4,5,6], [7], [8,9]]*99' '[item for sublist in l for item in sublist]'10000 loops, best of 5: 21.7 usec per loop$ python3 -mtimeit -s'l=[[1,2,3],[4,5,6], [7], [8,9]]*99' 'sum(l, [])'1000 loops, best of 5: 258 usec per loop$ python3 -mtimeit -s'l=[[1,2,3],[4,5,6], [7], [8,9]]*99;from functools import reduce' 'reduce(lambda x,y: x+y,l)'1000 loops, best of 5: 292 usec per loop$ python3 --versionPython 3.7.5rc1
import numpy
l = [[1, 2, 3], [4, 5, 6], [7], [8, 9]] * 99
%timeit numpy.concatenate(l).ravel().tolist()1000 loops, best of 3: 313 µs per loop
%timeit numpy.concatenate(l).tolist()1000 loops, best of 3: 312 µs per loop
%timeit [item for sublist in l for item in sublist]1000 loops, best of 3: 31.5 µs per loop
from itertools import chainfrom functools import reducefrom collections import Iterable # or from collections.abc import Iterableimport operatorfrom iteration_utilities import deepflatten
def nested_list_comprehension(lsts):return [item for sublist in lsts for item in sublist]
def itertools_chain_from_iterable(lsts):return list(chain.from_iterable(lsts))
def pythons_sum(lsts):return sum(lsts, [])
def reduce_add(lsts):return reduce(lambda x, y: x + y, lsts)
def pylangs_flatten(lsts):return list(flatten(lsts))
def flatten(items):"""Yield items from any nested iterable; see REF."""for x in items:if isinstance(x, Iterable) and not isinstance(x, (str, bytes)):yield from flatten(x)else:yield x
def reduce_concat(lsts):return reduce(operator.concat, lsts)
def iteration_utilities_deepflatten(lsts):return list(deepflatten(lsts, depth=1))
from simple_benchmark import benchmark
b = benchmark([nested_list_comprehension, itertools_chain_from_iterable, pythons_sum, reduce_add,pylangs_flatten, reduce_concat, iteration_utilities_deepflatten],arguments={2**i: [[0]*5]*(2**i) for i in range(1, 13)},argument_name='number of inner lists')
b.plot()
from typing import Iterable#from collections import Iterable # < py38
def flatten(items):"""Yield items from any nested iterable; see Reference."""for x in items:if isinstance(x, Iterable) and not isinstance(x, (str, bytes)):for sub_x in flatten(x):yield sub_xelse:yield x
备注:
在Python 3中,yield from flatten(x)可以替换for sub_x in flatten(x): yield sub_x
from typing import List
def flatten(l: list) -> List[int]:"""Flatten an arbitrary deep nested list of lists of integers.
Examples:>>> flatten([1, 2, [1, [10]]])[1, 2, 1, 10]
Args:l: Union[l, Union[int, List[int]]
Returns:Flatted list of integer"""return [int(i.strip('[ ]')) for i in str(l).split(',')]
Average time over 1000 trials of matplotlib.cbook.flatten: 2.55e-05 secAverage time over 1000 trials of underscore._.flatten: 4.63e-04 sec(time for underscore._)/(time for matplotlib.cbook) = 18.1233394636
>>> from collections import Iterable>>> from six import string_types
>>> def flatten(obj):... for i in obj:... if isinstance(i, Iterable) and not isinstance(i, string_types):... yield from flatten(i)... else:... yield i
>>> list(flatten(obj))[1, 2, 3, 4, 5, 6, 'abc', 7, 8, 9, 10]
def flatten(iterable):# These types won't considered a sequence or generally a containerexclude = str, bytes
for i in iterable:try:if isinstance(i, exclude):raise TypeErroriter(i)except TypeError:yield ielse:yield from flatten(i)
from collections.abc import Iterable
def flatten(items, ignore_types=(bytes, str)):"""Flatten all of the nested lists to the one. Ignoring flatting of iterable types str and bytes by default."""for x in items:if isinstance(x, Iterable) and not isinstance(x, ignore_types):yield from flatten(x)else:yield x
values = [7, [4, 3, 5, [7, 3], (3, 4), ('A', {'B', 'C'})]]
for v in flatten(values):print(v)