垂直或水平地计算列表列表中的值 "in a row"
Counting values "in a row" in list of lists vertically or horizontally
我正在编写一个函数,用于计算列表列表的特定值在水平或垂直方向的行中出现的次数。然后它只需要 return 它发生了多少次的值。这是一个例子
lst=[['.','.','.','e'],
['A','A','.','e'],
['.','.','.','e'],
['.','X','X','X'],
['.','.','.','.'],
['.','.','.','e']]
对于这个列表列表,函数应该 return 3 表示 e,因为它连续出现 3 次,2 表示 A,3 表示 X。感谢您的宝贵时间
到目前为止我的代码:
def length_of_row(symbol,lot):
count = 0
for sublist in lot:
for x in sublist:
if x == symbol:
count += 1
continue
else:
continue
return count
这实际上是一个很难用基本原理来解决的问题,如果你刚开始学习编程,会特别难。这是一个简洁但更高级的解决方案:
result = {}
for grid in [lst, zip(*lst)]:
for row in grid:
for key, group in itertools.groupby(row):
result[key] = max(len(list(group)), result.get(key, 0))
那么result
就是:
{'A': 2, 'X': 3, 'e': 3, '.': 4}
如果您不介意稍微改变一下,可以尝试以下方法:
from functools import reduce
from itertools import takewhile
def length_of_row(symbol, lot):
if symbol not in reduce(lambda x,y: x+y, lot):
return 0
elif symbol in lot[0]:
good_lot = map(lambda y: y.count(symbol),takewhile(lambda x: symbol in x, lot))
return sum(good_lot)
else:
return length_of_row(symbol, lot[1:])
这结合了递归和 python 的强大功能之一 itertools
methods (takewhile
)。这个想法是计算符号的数量,直到您找到一个不包含该符号的列表。此外,它会尝试确保仅在所述符号在列表列表中时才计算该符号的出现次数。
使用它:
lst = [['.', '.', '.', 'e'],
['A', 'A', '.', 'e'],
['.', '.', '.', 'e'],
['.', 'X', 'X', 'X'],
['.', '.', '.', '.'],
['.', '.', '.', 'e']]
print(length_of_row('e', lst))
print(length_of_row('X', lst))
print(length_of_row('A', lst))
print(length_of_row('f', lst))
#3
#3
#2
#0
如您所见,如果符号不存在它 returns 0
.
编辑:
如果您不想从 itertools
导入 takewhile
函数,您可以使用文档中提供的近似定义。但请记住,它不像 itertools
方法那样优化:
def takewhile(predicate, iterable):
for x in iterable:
if predicate(x):
yield x
else:
break
此外,如果您使用 python2
,reduce
应该可以直接使用。但是,您可以定义一个函数来将列表列表缩减为一个列表,如下所示:
def reduce_l_of_l(lst_of_lst):
out_lst = []
for lst in lst_of_lst:
out_lst += lst
return out_lst
不是使用reduce
,而是在定义后将其替换为reduce_l_of_l
。
希望对您有所帮助。
我正在编写一个函数,用于计算列表列表的特定值在水平或垂直方向的行中出现的次数。然后它只需要 return 它发生了多少次的值。这是一个例子
lst=[['.','.','.','e'],
['A','A','.','e'],
['.','.','.','e'],
['.','X','X','X'],
['.','.','.','.'],
['.','.','.','e']]
对于这个列表列表,函数应该 return 3 表示 e,因为它连续出现 3 次,2 表示 A,3 表示 X。感谢您的宝贵时间
到目前为止我的代码:
def length_of_row(symbol,lot):
count = 0
for sublist in lot:
for x in sublist:
if x == symbol:
count += 1
continue
else:
continue
return count
这实际上是一个很难用基本原理来解决的问题,如果你刚开始学习编程,会特别难。这是一个简洁但更高级的解决方案:
result = {}
for grid in [lst, zip(*lst)]:
for row in grid:
for key, group in itertools.groupby(row):
result[key] = max(len(list(group)), result.get(key, 0))
那么result
就是:
{'A': 2, 'X': 3, 'e': 3, '.': 4}
如果您不介意稍微改变一下,可以尝试以下方法:
from functools import reduce
from itertools import takewhile
def length_of_row(symbol, lot):
if symbol not in reduce(lambda x,y: x+y, lot):
return 0
elif symbol in lot[0]:
good_lot = map(lambda y: y.count(symbol),takewhile(lambda x: symbol in x, lot))
return sum(good_lot)
else:
return length_of_row(symbol, lot[1:])
这结合了递归和 python 的强大功能之一 itertools
methods (takewhile
)。这个想法是计算符号的数量,直到您找到一个不包含该符号的列表。此外,它会尝试确保仅在所述符号在列表列表中时才计算该符号的出现次数。
使用它:
lst = [['.', '.', '.', 'e'],
['A', 'A', '.', 'e'],
['.', '.', '.', 'e'],
['.', 'X', 'X', 'X'],
['.', '.', '.', '.'],
['.', '.', '.', 'e']]
print(length_of_row('e', lst))
print(length_of_row('X', lst))
print(length_of_row('A', lst))
print(length_of_row('f', lst))
#3
#3
#2
#0
如您所见,如果符号不存在它 returns 0
.
编辑:
如果您不想从 itertools
导入 takewhile
函数,您可以使用文档中提供的近似定义。但请记住,它不像 itertools
方法那样优化:
def takewhile(predicate, iterable):
for x in iterable:
if predicate(x):
yield x
else:
break
此外,如果您使用 python2
,reduce
应该可以直接使用。但是,您可以定义一个函数来将列表列表缩减为一个列表,如下所示:
def reduce_l_of_l(lst_of_lst):
out_lst = []
for lst in lst_of_lst:
out_lst += lst
return out_lst
不是使用reduce
,而是在定义后将其替换为reduce_l_of_l
。
希望对您有所帮助。