5

たとえば、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
4

5 に答える 5

4

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
于 2013-08-04T05:41:37.093 に答える
2

リストを平坦化してから呼び出すことができます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
于 2013-08-04T05:40:01.700 に答える
2

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
于 2013-08-04T06:16:02.130 に答える
2

任意のネストで機能する@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)
于 2013-08-04T07:54:42.230 に答える
0

どう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]
于 2013-08-04T05:44:14.520 に答える