Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/287.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 将字典转换为按值排序的列表,每个项具有多个值_Python_Dictionary - Fatal编程技术网

Python 将字典转换为按值排序的列表,每个项具有多个值

Python 将字典转换为按值排序的列表,每个项具有多个值,python,dictionary,Python,Dictionary,在Python中,我遇到了一个转换列表和字典的简单问题,我使用显式类型检查来区分整数和整数列表之间的差异。我对python有点陌生,我想知道是否有一种更“pythonic”的方法来解决这个问题,即避免显式类型检查 简而言之:尝试使用值对字典的键进行排序,但是每个键可以有多个值,并且该键需要在列表中出现多次。数据的形式为{'a':1,'b':[0,2],…}。我遇到的所有问题(使用sorted(,key=))都会因为一次出现的值不能指定为整数而不是列表1的长度而出错 我想在形式为{'a':3,'b

在Python中,我遇到了一个转换列表和字典的简单问题,我使用显式类型检查来区分整数和整数列表之间的差异。我对python有点陌生,我想知道是否有一种更“pythonic”的方法来解决这个问题,即避免显式类型检查

简而言之:尝试使用值对字典的键进行排序,但是每个键可以有多个值,并且该键需要在列表中出现多次。数据的形式为
{'a':1,'b':[0,2],…}
。我遇到的所有问题(使用sorted(,key=))都会因为一次出现的值不能指定为整数而不是列表1的长度而出错

我想在形式为
{'a':3,'b':0,'c':[2,4],'d':[1,5]}
的字典和列表之间进行转换(列表中项目的位置由字典中的值指定)

函数
list\u to\u dictionary
应该为列表中出现的每个项目提供一个键,该键的值给出了列表中的位置。如果某个项目出现多次,则该值应为存储所有这些位置的列表

函数
dictionary\u to\u list
应创建一个由字典键组成的列表,按值排序。如果该值不是单个整数而是整数列表,则该键应在相应的排序位置多次出现在列表中

我的解决办法如下:

def dictionary_to_list(d):
"""inputs a dictionary a:i or a:[i,j], outputs a list of a sorted by i"""    
    #Converts i to [i] as value of dictionary
    for a in d:
        if type(d[a])!=type([0,1]):
            d[a] = [d[a]]

    #Reverses the dictionary from {a:[i,j]...} to {i:a, j:a,...}
    reversed_d ={i:a for a in d for i in d[a]}

    return  [x[1] for x in sorted(reversed_d.items(), key=lambda x:x[0])]

def list_to_dictionary(x):
    d = {}        
    for i in range(len(x)):
        a = x[i]            
        if a in d:
            d[a].append(i)
        else:
            d[a]=[i]
    #Creates {a:[i], b:[j,k],...}

    for a in d:
        if len(d[a])==1:
            d[a] = d[a][0]
    #Converts to {a:i, b:[j,k],...}

    return d
由于与其余代码的交互,我无法将问题更改为使用长度为1的列表代替单个整数作为字典的值。似乎应该有一个简单的方法来处理这个问题,但我想不出来。这里更好的解决方案是为我的python脚本提供几个应用程序

谢谢

输出

['b', 'd', 'c', 'a', 'c', 'd']
{'a': 3, 'c': [2, 4], 'b': 0, 'd': [1, 5]}
呼吁:

sorted(
  list(
    itertools.chain.from_iterable(
      [[k]*(1 if isinstance(d[k], int) else len(d[k])) 
        for k in d
      ]
    )
  ), 
  key=lambda i:d[i] if isinstance(d[i], int) else d[i].pop(0)
)
其思想是,第一部分(即
列表(itertools.chain.from_iterable([[k]*(1 if isinstance(d[k],int)else len(d[k])表示k in d])
创建
d
中的键列表,并按与之相关联的值的数量重复。因此,如果一个键具有单个
int
(或仅包含一个
int
的列表)作为其值,它在此列表中显示一次;否则,它的显示次数与列表中的项目相同

接下来,我们假设对值进行了排序(否则,作为预处理步骤很简单)。因此,现在我们要做的是按键的第一个值对键进行排序。如果键的值只有一个int,则考虑该值;否则,列表中包含其所有值的第一个元素。第一个元素也将从列表中删除(通过调用pop)使同一个键的后续出现不会重用相同的值

如果希望在不进行显式类型检查的情况下执行此操作,则可以将所有值作为预处理步骤列出:

In [22]: d = {'a':3, 'b':0, 'c':[2,4], 'd':[1,5]}

In [23]: d = {k:v if isinstance(v, list) else [v] for k,v in d.iteritems()}

In [24]: d
Out[24]: {'a': [3], 'b': [0], 'c': [2, 4], 'd': [1, 5]}

In [25]: sorted(list(itertools.chain.from_iterable([[k]*len(d[k]) for k in d])), key=lambda i:d[i].pop(0))
Out[25]: ['b', 'd', 'c', 'a', 'c', 'd']

您可以尝试将dict中的值表示统一为始终为列表。这样,您就不需要将它们消歧为int或list。您的示例将成为:
{'a':[3],'b':[0],'c':[2,4],'d':[1,5]}
我认为如果不检查类型就很难做到这一点。这当然是我想到的第一个想法。但是,这段代码是一个更大的程序的一部分,在这个程序中,每个键只有一个项目是有意义的-每个键有两个项目的情况只是中间步骤。我经常在程序中使用这个字典的值ms,而且总是多放一个[0]似乎有点不礼貌在任何地方我都需要这个值。但是,我需要在这些字典上执行的其他操作都很容易以列表格式执行:例如,连接列表,或者从列表中删除两个“c”实例,其中索引会适当地移动。仍然需要检查
v
的类型。您认为如果没有它,就不可能执行此操作吗有检查吗?我有。要么在创建时检查,要么执行预处理步骤。在这两种情况下,都需要检查。如果您感觉更好,请将其分配给函数
sorted(
  list(
    itertools.chain.from_iterable(
      [[k]*(1 if isinstance(d[k], int) else len(d[k])) 
        for k in d
      ]
    )
  ), 
  key=lambda i:d[i] if isinstance(d[i], int) else d[i].pop(0)
)
In [22]: d = {'a':3, 'b':0, 'c':[2,4], 'd':[1,5]}

In [23]: d = {k:v if isinstance(v, list) else [v] for k,v in d.iteritems()}

In [24]: d
Out[24]: {'a': [3], 'b': [0], 'c': [2, 4], 'd': [1, 5]}

In [25]: sorted(list(itertools.chain.from_iterable([[k]*len(d[k]) for k in d])), key=lambda i:d[i].pop(0))
Out[25]: ['b', 'd', 'c', 'a', 'c', 'd']
def dictionary_to_list(d):
    return [k[0] for k in sorted(list(((key,n) for key, value in d.items() if isinstance(value, list) for n in value))+\
    [(key, value) for key, value in d.items() if not isinstance(value, list)], key=lambda k:k[1])]

def list_to_dictionary(l):
    d = {}
    for i, c in enumerate(l):
        if c in d:
            if isinstance(d[c], list):
                d[c].append(i)
            else:
                d[c] = [d[c], i]
        else:
            d[c] = i
    return d
l = dictionary_to_list({'a':3, 'b':0, 'c':[2,4], 'd':[1,5]})
print(l)
print(list_to_dictionary(l))