no_sleep
no_sleep

Reputation: 83

Assign values to dictionary by order they were added

Pretty much what the title says, I want to create a dictionary with phone numbers as keys and every time a new number is added I want its value to increment by one.

Like this: {'7806969':1 , '78708708' : 2} and etc...

nodes=[1,2,3,4,5,6,7,8,9]

customers=open('customers.txt','r')
calls=open('calls.txt.','r')
sorted_no={}
for line in customers:
    rows=line.split(";")
    if rows[0] not in sorted_no:
        sorted_no[rows[0]]=nodes[0]
    else:
        sorted_no[rows[0]]= 
print(sorted_no)

That was the code I have so far, I tried creating a list for my problem but that plan quickly fell apart.

Upvotes: 1

Views: 103

Answers (3)

Padraic Cunningham
Padraic Cunningham

Reputation: 180401

use a defaultdict and just sort the output if you actually want it sorted by least to most frequent:

sorted_no = defaultdict(int)
for line in customers:
    rows = line.split(";")
    sorted_no[rows[0]] += 1

Or just use a Counter dict:

from collections import Counter
with open('customers.txt') as customers:
    c = Counter(line.split(";")[0] for line in customers )
    print(c.most_common())

To actually just increment the count per element and because you have no duplicates use enumerate :

with open('customers.txt') as customers:
    sorted_no = {}
    for ind, line in enumerate(customers,1):
        rows=line.split(";")
        sorted_no[rows[0]] = ind

Or as a dict comprehension:

with open('customers.txt') as customers:
    sorted_no = {line.split(";")[0]:ind for ind, line in enumerate(customers,1)}

If order is important simply use:

 from collections import OrderedDict
 sorted_no =  OrderedDict()

 with open('customers.txt') as customers:
     sorted_no = OrderedDict((line.split(";")[0], ind) for ind, line in enumerate(customers,1))

enumerate(customers,1) gives every index of each line in customers but we pass in 1 as the start index so we start at 1 instead of 0.

Upvotes: 3

Reut Sharabani
Reut Sharabani

Reputation: 31339

This is probably one of the shorter ways to do it (thank Jon Clements in comments):

#!/usr/bin/env python3.4

from collections import defaultdict
import itertools

sorted_no = defaultdict(itertools.count(1).__next__)
for line in customers:
    rows=line.split(";")
    # no need to put anything,
    # just use the key and it increments automagically.
    sorted_no[rows[0]]

itertools.count(1) produces a generator, which is equivalent (roughly) to:

def lazy():
    counter = 0
    while True:
        counter += 1
        yield counter

I left my original answer so people can learn about the default-binding gotcha, or maybe even use it if they want:

#!/usr/bin/env python3.4

from collections import defaultdict

def lazy_gen(current=[0]):
    current[0] += 1
    return current[0]

sorted_no = defaultdict(lazy_gen)
for line in customers:
    rows=line.split(";")
    # no need to put anything,
    # just use the key and it increments automagically.
    sorted_no[rows[0]]

It works because Python's default assignment happens once, and when you use a mutable object (list in this case), you can change the function's return value dynamically.

It's a little wierd though :)

Upvotes: 0

DSM
DSM

Reputation: 353059

If I understand you, all you need to do is increase the number you're using as you go:

sorted_no = {}
with open("customers.txt") as fp:
    for line in fp:
        number = line.split(";")[0]
        if number not in sorted_no:
            sorted_no[number] = len(sorted_no) + 1

This produces something like

{'7801234567': 4,
 '7801236789': 6,
 '7803214567': 9,
 '7804321098': 7,
 '7804922860': 3,
 '7807890123': 1,
 '7808765432': 2,
 '7808907654': 5,
 '7809876543': 8}

where the first unique phone number seen gets 1, and the second 2, etc.

Upvotes: 2

Related Questions