I have some code where I am using a list of names, and a file (eventually multiple files) of results (team, name, place). The end result I am looking for is to have each person
IIUC, your dictionary is mapping place
to score
. You can leverage a defaultdict to replace your fromkeys
method:
from collections import defaultdict
# Initialize an empty dictionary as you've done with default list entries
scores = defaultdict(list)
# Using the with context manager allows for safe file handling
with open("ResultsTest.txt", 'r') as f1:
lines = f1.read().splitlines()
# Points lookup as you've done before
lookup = {1: 100, 2: 90, 3: 80}
for l in lines:
team, name, place = l.split('\t') # unpacking makes this way more readable
score = lookup.get(int(place))
scores[team].append(score)
The problem you encounter comes from the way you create Scores
:
Scores=dict.fromkeys(lines,[])
When using dict.fromkeys
, the same value is used for all keys of the dict. Here, the same, one and only empty list is the common value for all your keys. So, whichever key you access it through, you always update the same list.
When doing Scores[a[1]]=[]
, you actually create a new, different empty list, that becomes the value for the key a[1]
only, so the problem disappears.
You could create the dict differently, using a dict comprehension:
Scores = {key: [] for key in lines} # here, a new empty list is created for each key
or use a collections.defaultdict
from collections import defaultdict
Scores = defaultdict(list)
which will automatically initialize Score['your_key']
to an empty list when needed.
By using Scores=dict.fromkeys(lines,[])
you're initializing every key of the dict with a reference to the same list, so changes made to the list are reflected across all keys. You can use a dict comprehension for initialization instead:
Scores = {line: [] for line in lines}
Alternatively, you can initialize Scores
as a normal dict {}
and use the dict.setdefault
method to initialize its keys with lists:
Scores.setdefault(a[1], []).append(score)