例如,我有一个 2D 列表mylist =[[1,2,3],[4,5,6],[7,8,9]]
。
有什么方法可以使用len()
函数来计算数组索引的长度?例如:
len(mylist[0:3])
len(mylist[1:3])
len(mylist[0:1])
应该给:
9
6
3
例如,我有一个 2D 列表mylist =[[1,2,3],[4,5,6],[7,8,9]]
。
有什么方法可以使用len()
函数来计算数组索引的长度?例如:
len(mylist[0:3])
len(mylist[1:3])
len(mylist[0:1])
应该给:
9
6
3
length = sum([len(arr) for arr in mylist])
sum([len(arr) for arr in mylist[0:3]]) = 9
sum([len(arr) for arr in mylist[1:3]]) = 6
sum([len(arr) for arr in mylist[2:3]]) = 3
将每个列表的长度相加mylist
得到所有元素的长度。
这只有在列表是 2D 时才能正常工作。如果 的某些元素mylist
不是列表,谁知道会发生什么……
此外,您可以将其绑定到一个函数:
len2 = lambda l: sum([len(x) for x in l])
len2(mylist[0:3]) = 9
len2(mylist[1:3]) = 6
len2(mylist[2:3]) = 3
您可以展平列表,然后调用len
它:
>>> mylist=[[1,2,3],[4,5,6],[7,8,9]]
>>> import collections
>>> def flatten(l):
... for el in l:
... if isinstance(el, collections.Iterable) and not isinstance(el, basestring):
... for sub in flatten(el):
... yield sub
... else:
... yield el
...
>>> len(list(flatten(mylist)))
9
>>> len(list(flatten(mylist[1:3])))
6
>>> len(list(flatten(mylist[0:1])))
3
您可以reduce
像这样使用来计算数组索引的长度,这也可以在您传入以下内容时处理这种情况mylist[0:0]
:
def myLen(myList):
return reduce(lambda x, y:x+y, [len(x) for x in myList], 0)
myLen(mylist[0:3]) = 9
myLen(mylist[1:3]) = 6
myLen(mylist[0:1]) = 3
myLen(mylist[0:0]) = 0
我喜欢@Haidro 的答案,它适用于任意嵌套,但我不喜欢中间列表的创建。这是一个避免这种情况的变体。
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
最重要的是,我还包含了一个生成器驱动的、完全递归flatten
的。请注意,这次对字符串做出更难的决定(上面的短路是非常正确的,因为 as 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
如果你不需要任意嵌套——如果你总是确定这只是一个列表列表(或元组列表、列表元组等)——“最佳”方法可能是简单的“生成器之和” @Matt Bryant 答案的变体:
len2 = lambda lst: sum(len(x) for x in lst)
怎么样len(ast.flatten(lst))
?仅适用于 py2k afaik
它是
from compiler import ast
len(ast.flatten(lst))
自从
ast.flatten([1,2,3]) == [1,2,3]
ast.flatten(mylist[0:2]) == [1,2,3,4,5,6]
ast.flatten(mylist) == [1,2,3,4,5,6,7,8,9]