使用另一个枚举列表作为键的更优雅的列表理解
More elegant list comprehension using another enumerated list as a key
我有一个列表列表:
>>> array = [["A","B","C"],["C","B","A"]]
我还有一个我用枚举创建的密钥:
>>> key = list(enumerate(["A","B","C"]))
>>> print (key)
[(0,"A"),(1,"B"),(2,"C")]
我想使用列表理解将数组中的字符串根据键转换为数字。我做了以下并且能够得到我想要的结果:
>>> for i in key:
... board = [[i[0] if x in i else x for x in y] for y in board]
>>> print(board)
[[0,1,2],[2,1,0]]
但是,我似乎无法弄清楚如何在没有 for 循环的情况下使用单个列表理解来获取结果。关于我将如何做到这一点有什么想法吗?
如果我没理解错的话,你想将 for-loop
转换为列表理解。您可以创建一个映射(在您的问题中,这是倒置的 key
dictionary`),然后使用列表理解:
array = [["A","B","C"],["C","B","A"]]
mapper = {v:k for k, v in dict(enumerate(["A","B","C"])).items()}
print( [[mapper[v] for v in subl] for subl in array] )
打印:
[[0, 1, 2], [2, 1, 0]]
编辑:感谢@kaya3,仅枚举的较轻版本:
array = [["A","B","C"],["C","B","A"]]
mapper = {v:k for k, v in enumerate(["A","B","C"])}
print( [[mapper[v] for v in subl] for subl in array] )
您可以使用 defaultdict
长度技巧在单次迭代中按出现顺序获得唯一的整数表示:
from collections import defaultdict
d = defaultdict(lambda: len(d))
array = [["A", "B", "C"], ["C", "B", "A"]]
array = [[d[x] for x in sub] for sub in array]
# [[0, 1, 2], [2, 1, 0]]
使用 python 3.8,您可以在一行中使用与@AndrejKesely 相同的方法,通过列表理解内的 walrus-operator 创建 mapper
:
array = [["A","B","C"],["C","B","A"]]
arr2 = [[ mapper[p] for p in l] for l in array
if (mapper := {v:k for k,v in enumerate(array[0])})]
print(arr2)
输出:
[[0, 1, 2], [2, 1, 0]]
您可以将 key
变成字典,将字母映射到它们的索引,然后进行映射:
letters = ['A', 'B', 'C']
array = [['A', 'B', 'C'], ['C', 'B', 'A']]
key = {x: i for i, x in enumerate(letters)}
array = [list(map(key.get, row)) for row in array]
或者,由于 letters
很短,letters.index
足够有效,因此根本没有必要构建密钥:
letters = ['A', 'B', 'C']
array = [['A', 'B', 'C'], ['C', 'B', 'A']]
array = [list(map(letters.index, row)) for row in array]
我有一个列表列表:
>>> array = [["A","B","C"],["C","B","A"]]
我还有一个我用枚举创建的密钥:
>>> key = list(enumerate(["A","B","C"]))
>>> print (key)
[(0,"A"),(1,"B"),(2,"C")]
我想使用列表理解将数组中的字符串根据键转换为数字。我做了以下并且能够得到我想要的结果:
>>> for i in key:
... board = [[i[0] if x in i else x for x in y] for y in board]
>>> print(board)
[[0,1,2],[2,1,0]]
但是,我似乎无法弄清楚如何在没有 for 循环的情况下使用单个列表理解来获取结果。关于我将如何做到这一点有什么想法吗?
如果我没理解错的话,你想将 for-loop
转换为列表理解。您可以创建一个映射(在您的问题中,这是倒置的 key
dictionary`),然后使用列表理解:
array = [["A","B","C"],["C","B","A"]]
mapper = {v:k for k, v in dict(enumerate(["A","B","C"])).items()}
print( [[mapper[v] for v in subl] for subl in array] )
打印:
[[0, 1, 2], [2, 1, 0]]
编辑:感谢@kaya3,仅枚举的较轻版本:
array = [["A","B","C"],["C","B","A"]]
mapper = {v:k for k, v in enumerate(["A","B","C"])}
print( [[mapper[v] for v in subl] for subl in array] )
您可以使用 defaultdict
长度技巧在单次迭代中按出现顺序获得唯一的整数表示:
from collections import defaultdict
d = defaultdict(lambda: len(d))
array = [["A", "B", "C"], ["C", "B", "A"]]
array = [[d[x] for x in sub] for sub in array]
# [[0, 1, 2], [2, 1, 0]]
使用 python 3.8,您可以在一行中使用与@AndrejKesely 相同的方法,通过列表理解内的 walrus-operator 创建 mapper
:
array = [["A","B","C"],["C","B","A"]]
arr2 = [[ mapper[p] for p in l] for l in array
if (mapper := {v:k for k,v in enumerate(array[0])})]
print(arr2)
输出:
[[0, 1, 2], [2, 1, 0]]
您可以将 key
变成字典,将字母映射到它们的索引,然后进行映射:
letters = ['A', 'B', 'C']
array = [['A', 'B', 'C'], ['C', 'B', 'A']]
key = {x: i for i, x in enumerate(letters)}
array = [list(map(key.get, row)) for row in array]
或者,由于 letters
很短,letters.index
足够有效,因此根本没有必要构建密钥:
letters = ['A', 'B', 'C']
array = [['A', 'B', 'C'], ['C', 'B', 'A']]
array = [list(map(letters.index, row)) for row in array]