Reputation: 35
Hello I have a problem with my code for a project I am working on. I am currently trying to manipulate dictionaries and add things into them, but there is something weird going on with my code. The first step to my function is to take a text file that looks like this:
A;X;Y;Z
B;Y;Z;X
C;Y;Z;X
D;Z;X;Y
E;Z;X;Y
I then take the lines of text and put them into a dictionary. Example:
defaultdict(<class 'set'>, {'E': {'Z', 'X', 'Y'}, 'C': {'Y', 'Z', 'X'}, 'A': {'X', 'Y', 'Z'}, 'D': {'Z', 'X', 'Y'}, 'B': {'Y', 'Z', 'X'}})
I wrote the for loop to do this, but the problem I have is that when adding items to the dictionary the code mixes up the values in the dictionary for some reason.
def read_voter_preferences(file : open):
votes_dict = defaultdict(set)
for line in file:
line = line.strip().split(";")
for i in range(1,4):
print(votes_dict)
votes_dict[line[0]].add(line[i])
return votes_dict
The output is this: defaultdict(<class 'set'>, {'E': {'X', 'Y', 'Z'}, 'C': {'X', 'Y', 'Z'}, 'A': {'X', 'Y', 'Z'}, 'D': {'X', 'Y', 'Z'}, 'B': {'X', 'Y', 'Z'}})
When the code adds items into a dictionary, it mixes up the order of the items of the dictionary which is important for this particular project. How do I fix this? Does .add() automatically sort the items in the list? Thank you!
Upvotes: 0
Views: 278
Reputation: 882721
A set
, like a dict
, does not preserve order. If the order, as you say, is important, you must therefore use a list
, not a set
, to maintain it. So, if you're not worries about duplicates:
votes_dict = dict()
for line in file:
line = line.strip().split(";")
votes_dict[line[0]] = line[1:]
return votes_dict
Note that you don't really need a default_dict
here.
If you need to both maintain order and remove duplicates, your life is harder, but still not too terrible; e.g:
votes_dict = dict()
for line in file:
line = line.strip().split(";")
votes_dict[line[0]] = thelist = []
seen = set()
for item in line[1:]:
if item in seen: continue
thelist.append(item)
seen.add(item)
return votes_dict
You could cut corners, avoid creating and maintaining seen
, and use something like:
votes_dict = dict()
for line in file:
line = line.strip().split(";")
votes_dict[line[0]] = thelist = []
for item in line[1:]:
if item in thelist: continue
thelist.append(item)
return votes_dict
Checking in
with a list rather than a set is bad in general, but fine for a very short list as you have here, so this one may be best. (Giving a local name as an alias to the list you're building is a technique worth remembering -- no reason to repeatedly index votes_dict
:-).
Upvotes: 1
Reputation: 994659
The syntax
{'Z', 'X', 'Y'}
declares a set of items, where only membership is important, not order. So Python feels free to reorder the items when it displays the set.
To preserve the order, use a list:
['Z', 'X', 'Y']
Upvotes: 0