如何在 Python 中的嵌套列表中随机随机排列项目?
How to randomly shuffle items across nested list in Python?
我目前正在做一个 uni 项目,该项目要求我在嵌套列表中随机排列项目。
假设我有一个嵌套列表,其中包含一个人的姓名、他们晚餐吃的食物以及他们吃晚餐的时间,它看起来像这样:
food = [['person1', 'food1', 'dinner time1'],
['person2', 'food2', 'dinner time2'],
['person3', 'food3', 'dinner time3'],
...]
有什么办法可以随机重新排列列表,让每个人吃不同的食物和晚餐时间,看起来像这样:
food_reshuffle = [['person2', 'food3', 'dinner time3'],
['person1', 'food2', 'dinner time2'],
['person3', 'food1', 'dinner time1']
...]
您可以将列表分成 列 ,然后打乱每一列并重新组合它们。
要将列作为列表,请使用 zip()
function 并将外部列表应用为 单独的 参数,使用 *args
语法。 zip()
returns 个元组,但如果我们想洗牌,我们需要列表,所以我使用 map()
来转换每个元组。
people, foods, dinner_times = map(list, zip(*food))
因为每个行都作为参数传入,zip()
将每行的第一个值配对为一个元组,下一行为另一个元组,依此类推.
现在您有三个单独的列表,您可以将每个列表传递给 random.shuffle()
:
import random
random.shuffle(people)
random.shuffle(foods)
random.shuffle(dinner_times)
然后重新组合,再次与zip()
:
food_reshuffle = [list(row) for row in zip(people, foods, dinner_times)]
演示:
>>> from pprint import pprint
>>> import random
>>> food = [['person1', 'food1', 'dinner time1'],
... ['person2', 'food2', 'dinner time2'],
... ['person3', 'food3', 'dinner time3'],
... ]
>>> people, foods, dinner_times = map(list, zip(*food))
>>> random.shuffle(people)
>>> random.shuffle(foods)
>>> random.shuffle(dinner_times)
>>> food_reshuffle = [list(row) for row in zip(people, foods, dinner_times)]
>>> pprint(food_reshuffle)
[['person2', 'food2', 'dinner time1'],
['person3', 'food3', 'dinner time2'],
['person1', 'food1', 'dinner time3']]
如果你只想打乱 第一个 列,其他列作为一个整体打乱(所以你最终得到 'personA'
与 pair ('foodB', 'dinner timeB')
,然后我将洗牌外部列表或其副本 first,然后分离出 people 列进行洗牌和重组。避免必须制作副本,您可以使用 random.sample()
从输入序列中随机抽样,恰好 恰好 具有相同的长度。这恰好给出了相同的结果与使用 random.shuffle()
一样,但无需先复制输入序列并就地随机播放:
import random
shuffled = random.sample(food, len(food))
people, *other = zip(*shuffled)
food_reshuffle = [[p, *o] for p, o in zip(random.sample(people, len(people), *other)]
结果如下:
>>> shuffled = random.sample(food, len(food))
>>> people, *other = zip(*shuffled)
>>> food_reshuffle = [list(row) for row in zip(random.sample(people, len(people)), *other)]
>>> pprint(food_reshuffle)
[['person2', 'food2', 'dinner time2'],
['person1', 'food3', 'dinner time3'],
['person3', 'food1', 'dinner time1']]
我使用了另一个 'trick',其中我们将 zip(...)
的第一个结果分配给 people
并将 其他所有结果 分配给 other
,通过在作业中使用 *other
。
否则,如果您有可变数量的列都需要独立洗牌,只需在 zip(*food)
上使用循环并将每个洗牌后的列附加到 columns
列表中,这样您就可以重新组合那些又是 zip(*columns)
.
这很容易组合成一个函数:
import random
def shuffle_columns(list_of_rows):
columns = []
for column in zip(*list_of_rows):
# shuffled list of column values
shuffled = random.sample(column, len(column))
columns.append(shuffled)
return [list(row) for row in zip(*columns)]
如果您只想相对于其他列随机排列第一列,您可以提取并重新分配它:
first = [entry[0] for entry in people]
random.shuffle(first)
for entry, person in zip(people, first):
entry[0] = person
如果您需要打乱整个内容,您可以在第一列相对于其他列打乱后执行此操作:
random.shuffle(people)
如果你想按人排序,你也可以这样做:
people.sort()
我目前正在做一个 uni 项目,该项目要求我在嵌套列表中随机排列项目。
假设我有一个嵌套列表,其中包含一个人的姓名、他们晚餐吃的食物以及他们吃晚餐的时间,它看起来像这样:
food = [['person1', 'food1', 'dinner time1'],
['person2', 'food2', 'dinner time2'],
['person3', 'food3', 'dinner time3'],
...]
有什么办法可以随机重新排列列表,让每个人吃不同的食物和晚餐时间,看起来像这样:
food_reshuffle = [['person2', 'food3', 'dinner time3'],
['person1', 'food2', 'dinner time2'],
['person3', 'food1', 'dinner time1']
...]
您可以将列表分成 列 ,然后打乱每一列并重新组合它们。
要将列作为列表,请使用 zip()
function 并将外部列表应用为 单独的 参数,使用 *args
语法。 zip()
returns 个元组,但如果我们想洗牌,我们需要列表,所以我使用 map()
来转换每个元组。
people, foods, dinner_times = map(list, zip(*food))
因为每个行都作为参数传入,zip()
将每行的第一个值配对为一个元组,下一行为另一个元组,依此类推.
现在您有三个单独的列表,您可以将每个列表传递给 random.shuffle()
:
import random
random.shuffle(people)
random.shuffle(foods)
random.shuffle(dinner_times)
然后重新组合,再次与zip()
:
food_reshuffle = [list(row) for row in zip(people, foods, dinner_times)]
演示:
>>> from pprint import pprint
>>> import random
>>> food = [['person1', 'food1', 'dinner time1'],
... ['person2', 'food2', 'dinner time2'],
... ['person3', 'food3', 'dinner time3'],
... ]
>>> people, foods, dinner_times = map(list, zip(*food))
>>> random.shuffle(people)
>>> random.shuffle(foods)
>>> random.shuffle(dinner_times)
>>> food_reshuffle = [list(row) for row in zip(people, foods, dinner_times)]
>>> pprint(food_reshuffle)
[['person2', 'food2', 'dinner time1'],
['person3', 'food3', 'dinner time2'],
['person1', 'food1', 'dinner time3']]
如果你只想打乱 第一个 列,其他列作为一个整体打乱(所以你最终得到 'personA'
与 pair ('foodB', 'dinner timeB')
,然后我将洗牌外部列表或其副本 first,然后分离出 people 列进行洗牌和重组。避免必须制作副本,您可以使用 random.sample()
从输入序列中随机抽样,恰好 恰好 具有相同的长度。这恰好给出了相同的结果与使用 random.shuffle()
一样,但无需先复制输入序列并就地随机播放:
import random
shuffled = random.sample(food, len(food))
people, *other = zip(*shuffled)
food_reshuffle = [[p, *o] for p, o in zip(random.sample(people, len(people), *other)]
结果如下:
>>> shuffled = random.sample(food, len(food))
>>> people, *other = zip(*shuffled)
>>> food_reshuffle = [list(row) for row in zip(random.sample(people, len(people)), *other)]
>>> pprint(food_reshuffle)
[['person2', 'food2', 'dinner time2'],
['person1', 'food3', 'dinner time3'],
['person3', 'food1', 'dinner time1']]
我使用了另一个 'trick',其中我们将 zip(...)
的第一个结果分配给 people
并将 其他所有结果 分配给 other
,通过在作业中使用 *other
。
否则,如果您有可变数量的列都需要独立洗牌,只需在 zip(*food)
上使用循环并将每个洗牌后的列附加到 columns
列表中,这样您就可以重新组合那些又是 zip(*columns)
.
这很容易组合成一个函数:
import random
def shuffle_columns(list_of_rows):
columns = []
for column in zip(*list_of_rows):
# shuffled list of column values
shuffled = random.sample(column, len(column))
columns.append(shuffled)
return [list(row) for row in zip(*columns)]
如果您只想相对于其他列随机排列第一列,您可以提取并重新分配它:
first = [entry[0] for entry in people]
random.shuffle(first)
for entry, person in zip(people, first):
entry[0] = person
如果您需要打乱整个内容,您可以在第一列相对于其他列打乱后执行此操作:
random.shuffle(people)
如果你想按人排序,你也可以这样做:
people.sort()