如何通过每个列表中的第一个值将列表排序为字典中的值?

时间:2014-07-03 10:41:31

标签: python python-2.7

我有一个表,我想把3个列,部分名称,它的开头和结尾。我正在使用的代码是:

Contigs = {}
with open('ecoli.gtf', 'rb') as csvfile: # Opens file
    reader = csv.reader(csvfile, dialect=csv.excel_tab)
    for row in reader: #Iterates through each row
        if row[0] in Contigs: # Checks if chromosome or contigs id is already in the dict or not and then adds to it the correct start and end information
            Contigs[row[0]].append((row[3],row[4]))
        else:
            Contigs[row[0]] = [(row[3], row[4])]

这个工作非常好但是现在我想对数据进行排序,这样每个键都以最小的起始值开始,最大起作用,例如一个字典:

{'chr2':('24','200'),('50','70'),('1','30'),('30','80')}

这应该分类到:

{'chr2':('1','30'),('24','200'),('30','80'),('50','70')

这是因为起始编号为1,24,30,50。

我尝试过使用sort函数但是无法让它工作。我用于此的代码包括下面的示例,字典已命名为Contigs:

for key, value in Contigs:
    value.sort(key=lambda element: element[0])

Contigs.sort()

输出结果为

In [4]: Contigs.sort()
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-4-12fe6207fe40> in <module>()
----> 1 Contigs.sort()

AttributeError: 'dict' object has no attribute 'sort'



In [6]: %paste
for key, value in Contigs:
    value.sort(key=lambda element: element[0])

## -- End pasted text --
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-6-ecd309a55409> in <module>()
----> 1 for key, value in Contigs:
      2     value.sort(key=lambda element: element[0])

ValueError: too many values to unpack

我也在这里检查过以前的问题,这看起来很完美: Sorting by value in a dictionary if the value is a list

然而,当我运行下面的代码时,我会在屏幕上对角线输出输出,这些数字不在我的数据集中(通常是实数的两倍),因为最高的实数是在('273176', '273178'),   ('272071','273178'),以下代码提供的数字是('4639649','4639651'),(''4638965','4639651')]}

>>> from collections import OrderedDict
>>> mydict = OrderedDict(sorted(some_dict.items(), key=lambda x: x[1][0]))
>>> print(mydict)
OrderedDict([('a', [0, 0, 0, 0, 0]), ('c', [800, 30, 14, 14, 0]), ('b', [1400, 50, 30, 18, 0]), ('d', [5000, 100, 30, 50, 0.1]), ('for fun', [140000, 1400, 140, 140, 0.42])])
>>> print(mydict['a'])
[0, 0, 0, 0, 0]

我的一些实际数据的例子是:

{'chr': [('190', '192'),
  ('190', '252'),
  ('253', '255'),
  ('190', '255'),
  ('337', '339'),
  ('337', '2796'),
  ('2797', '2799')]}

3 个答案:

答案 0 :(得分:0)

您的问题是contigs.sort()您无法按密钥对字典进行排序。

如果你想要打印它,你必须提取密钥,对它们进行排序然后迭代它们

theKeys = contigs.keys()
theKeys.sort()
for k in theKeys;
  print contigs[k]

答案 1 :(得分:0)

Contigs是一个词典。通过dict迭代只会给你钥匙。为了获取键和值,您需要遍历dict.items()

for key, value in Contigs.items():
    value.sort(key=lambda element: int(element[0]))

(我还添加了转换为整数,否则20将在3之前。)

答案 2 :(得分:0)

您可以很容易地对dict的值进行排序,如下所示:

my_dict = {'chr': [('190', '192'),
                   ('190', '252'),
                   ('253', '255'),
                   ('190', '255'),
                   ('337', '339'),
                   ('337', '2796'),
                   ('2797', '2799')],
           "xxx": [(100, 25),
                   (12, 24),
                   (17, 800),
                   (35, 19)]}

for key in my_dict:
    my_dict[key].sort()

由于.sort()是就地操作,因此它会就地修改列表。但请注意,您正在排序字符串而不是数字,这将使'1000'排序小于'22',因此建议您在创建列表中插入的元组时将字符串转换为整数。另一种方法是使用类似

之类的东西来证明一个关键函数(或lambda)来对数值进行排序
    my_dict[key].sort(key=lambda t: int(t[0])

另请注意,通过使用collections.defaultdict,您可以为缺席密钥创建空列表。您的代码将如下所示:

from collections import defaultdict
Contigs = defaultdict(list) # list is called to create values for absent keys
with open('ecoli.gtf', 'rb') as csvfile: # Opens file
    reader = csv.reader(csvfile, dialect=csv.excel_tab)
    for row in reader: #Iterates through each row
        Contigs[row[0]].append((int(row[3]),int(row[4])))