让我们说我有一个游戏,其中玩家用唯一的数字表示。然后,说我有一堆随机选择的玩家名单,名为playerList。因此,列表没有被排序(例如,这可能代表一些玩家报名参加一些比赛)。然后,我有一个名为playerLevel的第二个列表,其中第i个条目告诉你第一个玩家所处的等级。
因此,如果playerLevel = ['X','Y','X','Z'],则玩家1和3在等级X上,玩家2在等级Y上,玩家4在等级Z上。
使用列表推导,我如何制作一个新的列表(让我们称之为相同级别),其中玩家编号被分类到子列表中,基于玩家处于同一级别?
所以,在这个例子中,sameLevel = [[1,3],[2],[4]]
我想以一种看起来优雅的方式做到这一点。理想情况下,使用一个主循环,看起来像“在playerLevel中的元素:”等等。我怎样才能做到这一点?谢谢!
答案 0 :(得分:3)
它本身不使用列表推导,但这样做:
from collections import defaultdict
playerLevel = ['X', 'Y', 'X', 'Z']
sameLevel = defaultdict(list)
for idx, level in enumerate(playerLevel):
sameLevel[level].append(idx)
print(sameLevel.values())
这会产生[[1], [0, 2], [3]]
。
答案 1 :(得分:2)
我会使用字典而不是嵌套列表:
In [1]: pLevels = ["X", "Y", "Z", "X"]
In [2]: from collections import defaultdict
In [3]: lvlPlayerMap = defaultdict(list)
In [4]: for (pID, lvl) in enumerate(pLevels): lvlPlayerMap[lvl].append(pID)
In [5]: lvlPlayerMap
Out[5]: defaultdict(list, {'X': [0, 3], 'Y': [1], 'Z': [2]})
答案 2 :(得分:0)
import operator, itertools
players = random.choices('xyzdeftup', k=20)
level = operator.itemgetter(1)
player = operator.itemgetter(0)
players = sorted(enumerate(players), key = level)
groups = itertools.groupby(players, key = level)
#for level, group in groups:
# print('{}:\n\t{}'.format(level, str(list(map(player, group)))))
result = [list(map(player, group)) for level, group in groups]
答案 3 :(得分:0)
使用itertools.groupby
的替代实现(wwii打败了我)。几个小时前,有人posted a question对这个确切的功能有用了。
<强>代码强>
import itertools
X = 5
Y = 10
Z = 15
PLAYER_LEVELS = [X, Y, X, Z]
def group_by_player_level(player_levels):
def by_level(pair):
return pair[1]
sorted_levels = sorted(enumerate(player_levels), key=by_level)
return [[i + 1 for (i, _) in g] for _, g in itertools.groupby(sorted_levels, key=by_level)]
if __name__ == '__main__':
print(group_by_player_level(PLAYER_LEVELS))
<强>输出强>
[[1, 3], [2], [4]]