0

The input file looks like this:

A 3.00 B 4.00 C 5.00 D 6.00
E 3.20 F 6.00 G 8.22
H 9.00 
I 9.23 J 89.2
K 32.344

And I am wanting the characters to be the keys in a dictionary while the floats being the values.

Here is the non-working fail that I have so far.

def main():
   #Input File
   reader = open('candidate.txt', 'r'

   my_dictionary = {}
   i=0
   for line in reader.readlines():
      variable = line.split(' ')[i]
      value = line.split(' ')[i+1]
      my_dictionary[variable]= value
      i+=2

      print my_dictionary

if __name__ == '__main__':
  main()
guettli
  • 25,042
  • 81
  • 346
  • 663
  • Think about your code for a moment. `i` gets increased by 2 for each line, right? So you get the first pair from line 1, the second from line 2, and so on, which is clearly not what you want, right? You need two nested for loops, one for lines and one to get all pairs within a line (if you want to keep using for loops - there are more efficient options, see guettli's answer for instance). – weronika Jul 03 '12 at 06:49
  • Basically, you need to iterate over items in your list in pairs (key, value). Here is an extensive answer showing different techniques: http://stackoverflow.com/questions/4628290/pairs-from-single-list - I like the `pairwise` function from the accepted answer. – Sergey Jul 03 '12 at 06:54
  • @user1497892 please accept an answer. Or add comments why the answers don't solve your problem. – guettli Jul 04 '12 at 06:46

3 Answers3

7
s='''A 3.00 B 4.00 C 5.00 D 6.00
E 3.20 F 6.00 G 8.22
H 9.00 
I 9.23 J 89.2
K 32.344
'''

s=s.split()
d=dict(zip(s[::2], s[1::2]))
print d

In context:

my_dict = dict()
for line in reader.readlines():
    pairs = line.split()
    for key, value in zip(pairs[::2],pairs[1::2]):
        my_dict[key] = value # strip() not needed
guettli
  • 25,042
  • 81
  • 346
  • 663
  • Hey! Thanks for the reply, but is there a way to do this without modifying the input file by adding quotes ? The input file is being given to me. – user1497892 Jul 03 '12 at 06:50
  • Very nice, although I wouldn't use this exact code if I was the OP. It's always better to avoid reading the whole file at once when possible. This code is a very concise demo of a nice idea, though. – Lev Levitsky Jul 03 '12 at 06:51
  • 1
    @user1497892, it's a [multiline string literal](http://docs.python.org/reference/lexical_analysis.html#string-literals). You don't need quotes in the input file. Also, to get the code to work, you need to know exactly what `readlines`, `readline` and `read` return on a file object. Please refer to the docs. – Lev Levitsky Jul 03 '12 at 06:56
0

Here is a solution using iterators that operates on a stream (and thus does not depending on reading the entire input first):

from itertools import izip

def group(iterable, n):
    """Yield iterable's items n at a time"""
    args = [iter(iterable)]*n
    return izip(*args)


def dictize(stream):
    r = {}
    for line in stream:
        for k,v in group(line.split(), 2):
            r[k] = v
    return r


from StringIO import StringIO

testinput = """A 3.00 B 4.00 C 5.00 D 6.00
E 3.20 F 6.00 G 8.22
H 9.00 
I 9.23 J 89.2
K 32.344"""

teststream = StringIO(testinput)

print dictize(teststream)

If you can use dictionary comprehensions, you can replace the dictize function with a one-liner:

print {k:v for line in teststream for k,v in group(line.split(),2)}
Francis Avila
  • 31,233
  • 6
  • 58
  • 96
0
with open('candidate.txt', 'r') as reader:
    print dict(zip(*[iter(reader.read().split())]*2))

With the opened file stream called reader we read it as a whole and then split it in pieces by whitespace. Now we have a list of words which we transform to an iterator and put it in a list and multiply it times 2 to make a list of two the same iterators. These are zipped into pairs as input for a dictionary.

Marco de Wit
  • 2,686
  • 18
  • 22