Lubię @Ha Odpowiedź idro, która działa dla dowolnego zagnieżdżenia, ale nie podoba mi się stworzenie listy pośredniej. Oto wariant, który tego unika.
try:
reduce
except NameError:
# python3 - reduce is in functools, there is no basestring
from functools import reduce
basestring = str
import operator
import collections
def rlen(item):
"""
rlen - recursive len(), where the "length" of a non-iterable
is just 1, but the length of anything else is the sum of the
lengths of its sub-items.
"""
if isinstance(item, collections.Iterable):
# A basestring is an Iterable that contains basestrings,
# i.e., it's endlessly recursive unless we short circuit
# here.
if isinstance(item, basestring):
return len(item)
return reduce(operator.add, (rlen(x) for x in item), 0)
return 1
Do cholery z tym podaję generator napędzany, w pełni rekurencyjne flatten
również. Zauważ, że tym razem jest trudniej podjąć decyzję o napisach (powyższe zwarcie jest trywialnie poprawne, ponieważ jako len(some_string) == sum(len(char) for char in some_string)
).
def flatten(item, keep_strings=False):
"""
Recursively flatten an iterable into a series of items. If given
an already flat item, just returns it.
"""
if isinstance(item, collections.Iterable):
# We may want to flatten strings too, but when they're
# length 1 we have to terminate recursion no matter what.
if isinstance(item, basestring) and (len(item) == 1 or keep_strings):
yield item
else:
for elem in item:
for sub in flatten(elem, keep_strings):
yield sub
else:
yield item
Jeśli nie trzeba arbitralne zagnieżdżanie-jeśli jesteś zawsze upewnić się, że jest to po prostu listę list (lub listę krotek, krotki list, etc) -the „najlepsza” metoda jest prawdopodobnie prosty wariant "suma generatora" @Matt Bryant's odpowiedź:
len2 = lambda lst: sum(len(x) for x in lst)
Nie trzeba używać rozumienia list. Generator jest szybszy. – Blender
Niż lista rozumienia? Trudno mi uwierzyć, że ... –
@MattBryant Oczywiście. 'sum (len (arr) dla arr w mylist [0: 3])' jest szybszy niż 'suma ([len (arr) dla arr w mojej liście [0: 3]])' – TerryA