Python 仅改组一个参数

Python shuffling only one parameter

我有一个 python 列表,我可以轻松地对其进行排序:

l2 = sorted(l1, key=lambda k: k["id"])
print l2

打印:

[ {'id': '02', 'time': 'bl' }, {'id': '02', 'time': 'm24' },  {'id': '05', 'time': 'bl' }, {'id': '05', 'time': 'm12' }, {'id': '05', 'time': 'm24' }, {'id': '09', 'time': 'm12' }]

但是我现在想使用 shuffle,仅根据 id 键来随机播放此列表,我想保留 相对顺序 time 键上。有办法做到这一点吗?

按相对顺序,我的意思是保留按键 time 的原始排序。例如,一个可能的解决方案是:

[ {'id': '09', 'time': 'm12' }, {'id': '05', 'time': 'bl' }, {'id': '05', 'time': 'm12' }, {'id': '05', 'time': 'm24' }, {'id': '02', 'time': 'bl' }, {'id': '02', 'time': 'm24' }]

可以检查每个 id.

项是否按键 time 部分排序

你想要的是将数据分组,然后打乱分组。

ids = list(set([id['id'] for id in l2]))
random.shuffle(ids)

l3 =[]
for id in ids:
    l3.extend([item for item in l2 if item['id']==id])

据我了解,您想打乱列表中的项目,但保持相似 ID 的 time 值的顺序。

l2 = [ {'id': '02', 'time': 'bl' }, {'id': '02', 'time': 'm24' },  {'id': '05', 'time': 'bl' }, {'id': '05', 'time': 'm12' }, {'id': '05', 'time': 'm24' }, {'id': '09', 'time': 'm12' }]
import random
ids = [id['id'] for id in l2]
random.shuffle(ids)
d = dict()
for id in set(ids):
    d[id] = [item for item in l2 if item['id'] == id]

l3 = []
for id in ids:
    l3.append(d[id].pop(0))

在我的例子中它打印了:

print ids
>>['05', '09', '02', '02', '05', '05']

print l2
>>[{'id': '02', 'time': 'bl'},
   {'id': '02', 'time': 'm24'},
   {'id': '05', 'time': 'bl'},
   {'id': '05', 'time': 'm12'},
   {'id': '05', 'time': 'm24'},
   {'id': '09', 'time': 'm12'}]

print l3
>>[{'id': '05', 'time': 'bl'},
   {'id': '09', 'time': 'm12'},
   {'id': '02', 'time': 'bl'},
   {'id': '02', 'time': 'm24'},
   {'id': '05', 'time': 'm12'},
   {'id': '05', 'time': 'm24'}]

在字典中构建列表时,您也可以使用生成器代替列表推导式:

for id in set(ids):
    d[id] = (c for c in l2 if c['id'] == id)
for id in ids:
    l3.append(next(d[id]))

感谢您的意见,我认为可行的解决方案是:

import random
# l2 is sorted totally:
l2 =[ {'id': '02', 'time': 'bl' }, {'id': '02', 'time': 'm24' },  {'id': '05', 'time': 'bl' }, {'id': '05', 'time': 'm12' }, {'id': '05', 'time': 'm24' }, {'id': '09', 'time': 'm12' }]
idss = set([i['id'] for i in l2])
ids = list(idss)

random.shuffle(ids)
l3 = []

for i in ids:
    for j in l2:
        if i == j['id']:
            # order by `time` is implicit
            l3.append(j)
print l3

没什么了不起的,因为我每次都需要遍历整个数组 l2,但是代码是可读的。

像这样?

from random import shuffle

l2 = [ {'id': '02', 'time': 'bl' }, {'id': '02', 'time': 'm24' },  {'id': '05', 'time': 'bl' }, {'id': '05', 'time': 'm12' }, {'id': '05', 'time': 'm24' }, {'id': '09', 'time': 'm12' }]
print(l2)

keys = [item['id'] for item in l2]
shuffle(keys)

for n in range(len(keys)):
    l2[n]['id'] = keys[n]

print(l2)

它打印:

>>> [{'id': '02', 'time': 'bl'}, {'id': '02', 'time': 'm24'}, {'id': '05', 'time': 'bl'}, {'id': '05', 'time': 'm12'}, {'id': '05', 'time': 'm24'}, {'id': '09', 'time': 'm12'}]
>>> [{'id': '02', 'time': 'bl'}, {'id': '09', 'time': 'm24'}, {'id': '05', 'time': 'bl'}, {'id': '02', 'time': 'm12'}, {'id': '05', 'time': 'm24'}, {'id': '05', 'time': 'm12'}]