Programming

사전에서 하나의 키에 여러 값을 추가합니다

procodes 2020. 7. 5. 21:35
반응형

사전에서 하나의 키에 여러 값을 추가합니다


이 질문에는 이미 답변이 있습니다.

나는 파이썬을 처음 접했고 매년 해와 값 목록을 가지고 있습니다. 내가 원하는 것은 연도가 이미 사전에 있는지 확인하고 존재하는 경우 특정 키의 해당 값 목록에 값을 추가하는 것입니다.예를 들어, 나는 연도 목록을 가지고 있으며 매년 하나의 가치를 가지고 있습니다.

2010  
2  
2009  
4  
1989  
8  
2009  
7  

내가하고 싶은 것은 년을 키로하고 그 한 자리 숫자를 값으로 사전을 채우는 것입니다. 그러나 2009를 두 번 나열한 경우 해당 사전의 값 목록에 두 번째 값을 추가하고 싶습니다.

2010: 2  
2009: 4, 7  
1989: 8  

지금 나는 다음을 가지고 있습니다.

d = dict()  
years = []  

(get 2 column list of years and values)

for line in list:    
    year = line[0]   
    value = line[1]  

for line in list:  
    if year in d.keys():  
        d[value].append(value)  
    else:  
        d[value] = value  
        d[year] = year  

질문을 다시 말할 수 있다면 원하는 연도를 키로 사용하고 매년 연도와 관련된 값 목록을 포함하는 배열을 가진 사전이 무엇입니까? 내가하는 방법은 다음과 같습니다.

years_dict = dict()

for line in list:
    if line[0] in years_dict:
        # append the new number to the existing array at this slot
        years_dict[line[0]].append(line[1])
    else:
        # create a new array in this slot
        years_dict[line[0]] = [line[1]]

years_dict에서 끝내야 할 것은 다음과 같은 사전입니다.

{
    "2010": [2],
    "2009": [4,7],
    "1989": [8]
}

일반적으로, "병렬 배열"을 작성하는 것은 좋지 않은 프로그래밍 관행입니다. 여기서, 항목은 둘 다를 포함하는 컨테이너의 적절한 하위 항목이 아닌 동일한 색인을 가짐으로써 서로 암시 적으로 연관됩니다.


 

collections.defaultdict

(Python 2.5에 추가됨)을 사용하는 것이 가장 좋습니다 . 이를 통해 누락 된 키의 기본 객체 유형 (예 : a

list

) 을 지정할 수 있습니다 .

So instead of creating a key if it doesn't exist first and then appending to the value of the key, you cut out the middle-man and just directly append to non-existing keys to get the desired result.

A quick example using your data:

>>> from collections import defaultdict
>>> data = [(2010, 2), (2009, 4), (1989, 8), (2009, 7)]
>>> d = defaultdict(list)
>>> d
defaultdict(<type 'list'>, {})
>>> for year, month in data:
...     d[year].append(month)
... 
>>> d
defaultdict(<type 'list'>, {2009: [4, 7], 2010: [2], 1989: [8]})

This way you don't have to worry about whether you've seen a digit associated with a year or not. You just append and forget, knowing that a missing key will always be a list. If a key already exists, then it will just be appended to.


You can use setdefault.

for line in list:  
    d.setdefault(year, []).append(value)

This works because setdefault returns the list as well as setting it on the dictionary, and because a list is mutable, appending to the version returned by setdefault is the same as appending it to the version inside the dictionary itself. If that makes any sense.


d = {} 

# import list of year,value pairs

for year,value in mylist:
    try:
        d[year].append(value)
    except KeyError:
        d[year] = [value]

The Python way - it is easier to receive forgiveness than ask permission!


Here is an alternative way of doing this using the not in operator:

# define an empty dict
years_dict = dict()

for line in list:
    # here define what key is, for example,
    key = line[0]
    # check if key is already present in dict
    if key not in years_dict:
        years_dict[key] = []
    # append some value 
    years_dict[key].append(some.value)

It's easier if you get these values into a list of tuples. To do this, you can use list slicing and the zip function.

data_in = [2010,2,2009,4,1989,8,2009,7]
data_pairs = zip(data_in[::2],data_in[1::2])

Zip takes an arbitrary number of lists, in this case the even and odd entries of data_in, and puts them together into a tuple.

Now we can use the setdefault method.

data_dict = {}
for x in data_pairs:
    data_dict.setdefault(x[0],[]).append(x[1])

setdefault takes a key and a default value, and returns either associated value, or if there is no current value, the default value. In this case, we will either get an empty or populated list, which we then append the current value to.


If you want a (almost) one-liner:

from collections import deque

d = {}
deque((d.setdefault(year, []).append(value) for year, value in source_of_data), maxlen=0)

Using dict.setdefault, you can encapsulate the idea of "check if the key already exists and make a new list if not" into a single call. This allows you to write a generator expression which is consumed by deque as efficiently as possible since the queue length is set to zero. The deque will be discarded immediately and the result will be in d.

This is something I just did for fun. I don't recommend using it. There is a time and a place to consume arbitrary iterables through a deque, and this is definitely not it.

참고URL : https://stackoverflow.com/questions/3199171/append-multiple-values-for-one-key-in-a-dictionary

반응형