risefire
risefire

Reputation: 49

How can i get a specific value from a key that has multiple values in it?

I am new to python.

As in title, I want to get a specific value from a key that multiple values.

I am trying to write a code that takes the first column as key and rest of the line as values in a text file. Then I want to get a specific value in the dictionary that has multiple values.

text file example:

111 Josh 12 17 20 21

112 Alice 13 18 25 24

113 Rick 15 17 30 21

This is pretty much what my code looks like:

Q=raw_input("Your ID") 
def f():
  d1={}
  with open('file.txt') as r:
    for line in r:
      (a,b,c,d,e,f)=line.split()
      if a==Q:
        d1[a]=b,c,d,e,f
  return d1
 
 
def f2():
  x=f()
  name=x[a,b]
  age=x[a,c]
  score1=x[a,d]
  score2=x[a,e]
  score3=x[a,f]
  print str(name)+ str(age) +str(score1)+ str(score2) +str(score3)

f2()

What I expect it to be:

112

Alice 13 18 25 24

p.s: by "x[a,b]" I mean, from d1, take a key's, b value.

p.s2: I am aware that the x[a,b] is wrong. I just wanted to show my intent.

Upvotes: 0

Views: 121

Answers (1)

Harvey
Harvey

Reputation: 5821

I think this is perhaps what you were trying to do. I made it work and improved it a little, but it still retains room for improvement (better naming, passing in file names, etc.).

import collections

# namedtuple is a regular tuple that can be accessed by name rather than just by position
NameRecord = collections.namedtuple("NameRecord", "id name age score1 score2 score3")

# Return the first record in file where the first element of the line
# matches the given id
def f(id):
  with open('file.txt') as r:
    for line in r:
        # Split the line and pass as arguments to a new NameRecord
        record = NameRecord(*line.split())
        if record.id == id:
            return record
  return None

def f2():
    id = raw_input("Your ID") 
    record = f(id)
    if record:
        #print '{} {} {} {} {}'.format(*record[1:])
        print '{} {} {} {} {}'.format(record.name,
                                      record.age,
                                      record.score1,
                                      record.score2,
                                      record.score3)
    else:
        print 'Id not found:', id

f2()

Another solution using generators. Unlike the first solution, this one will print all records matching id. If you only want the first, put a return statement inside the loop following the print statement.

NameRecord = collections.namedtuple("NameRecord", "id name age score1 score2 score3")

# generator from using yield
def lines_from_file(filename):
    with open(filename) as f:
        for line in f:
            yield line

# generator from generator expression
def name_records_from_lines(lines):
    return (NameRecord(*line.split()) for line in lines)

def name_records_matching_id(records, id):
    for record in records:
        if record.id == id:
            yield record

# identical to the method above for learning purposes
def name_records_matching_id_2(records, id):
    return (record for record in records if record.id == id)

id = raw_input("Your ID") 
lines = lines_from_file('file.txt')
records = name_records_from_lines(lines)
matching_records = name_records_matching_id(records, id)
# Note: if your code is simple enough, you don't need to define a method:
# matching_records = (record for record in records if record.id == id)
for record in matching_records:
    print record.name, record.age, record.score1, record.score2, record.score3

Upvotes: 1

Related Questions