对字典中列表的值进行排序

2024-04-26 08:08:09 发布

您现在位置:Python中文网/ 问答频道 /正文

我在字典里有超过9000个数据属性。简单版本如下所示:

test = {1092268: [81, 90], 524292: [80, 80], 892456: [88, 88]}

它们是基因id,在一个列表中有两个值。我想要的是得到多个包含所有id的字典,这些id的值高于或低于某个特定值。所以在这个例子中,假设我想要得到三个字典,一个包含的id和值都在85以下,另一个都在85以上,最后一个包含的第一个值在85以下,第二个在85以上。所以最后我会说:

testabove = { 892456: [88, 88]}  

以及

testbelow = { 524292: [80, 80]}

以及

testboth = { {1092268: [81, 90]} 

我不知道怎么弄清楚。你知道吗


Tags: 数据test版本id列表字典属性基因
3条回答

使用字典理解很简单

>>> testabove = {i:j for i,j in test.items() if j[0]>85 and j[1] > 85}
>>> testbelow = {i:j for i,j in test.items() if j[0]<85 and j[1] < 85}
>>> testboth = {i:j for i,j in test.items() if i not in testabove and i not in testbelow}
>>> testabove
{892456: [88, 88]}
>>> testbelow
{524292: [80, 80]}
>>> testboth
{1092268: [81, 90]}

正如Marein在下面的comments中提到的,另一种方法是

>>> test = {1092268: [81, 90], 524292: [80, 80], 892456: [88, 88]}
>>> testabove = {i:j for i,j in test.items() if all(x>85 for x in j)}
>>> testbelow = {i:j for i,j in test.items() if all(x<85 for x in j)}
>>> testabove
{892456: [88, 88]}
>>> testbelow
{524292: [80, 80]}

它使用^{}函数

比较

$ python -m timeit "test = {1092268: [81, 90], 524292: [80, 80], 892456: [88, 88]};testabove = {i:j for i,j in test.items() if all(x>85 for x in j)}"
100000 loops, best of 3: 2.29 usec per loop
$ python -m timeit "test = {1092268: [81, 90], 524292: [80, 80], 892456: [88, 88]};testabove = {i:j for i,j in test.items() if j[0]>85 and j[1] > 85}"
1000000 loops, best of 3: 0.99 usec per loop

如您所见,直截了当的方法比使用all更快。你知道吗

直接解决方案:

tmp = testboth, testabove, testbelow = {}, {}, {}
for k, v in test.items():
    tmp[(v[0] > 85 < v[1]) - (v[0] < 85 > v[1])][k] = v

它也比Bhargav的解决方案快,通过测试随机输入适当的大小来判断。测试和结果:

from random import *
test = {key: [randrange(170), randrange(170)] for key in sample(range(10000000), 9500)}
from timeit import timeit
print 'Bhargav', timeit(lambda: Bhargav(), number=100)
print 'Stefan', timeit(lambda: Stefan(), number=100)

Bhargav 1.87454111948
Stefan 1.2636884789

还有两种变化,不知道我最喜欢什么。你知道吗

testboth, testabove, testbelow = tmp = {}, {}, {}
for k, (a, b) in test.items():
    tmp[(a > 85 < b) - (a < 85 > b)][k] = [a, b]

for k, v in test.items():
    a, b = v
    tmp[(a > 85 < b) - (a < 85 > b)][k] = v

这些的计时大约是1.7秒和1.2秒。你知道吗

这是另一个对于大量数据应该更快的解决方案,因为它在一次迭代中构建了所有三个字典。你知道吗

def compare_both(xs,pivot):
 if xs[0] < pivot and xs[1] < pivot: return -1
 if xs[0] > pivot and xs[1] > pivot: return 1
 return 0

def sort_dict(d,pivot):
  dicts = [{},{},{}]
  for key,value in d.items():
    dicts[compare_both(value,pivot)+1][key] = value
  return dicts

相关问题 更多 >