1

I have two files with 6000 numerical values.I am giving just first 15 values of both.

base.txt
2.900000e+03
2.900000e+03
2.900000e+03
2.900000e+03
2.900000e+03
2.900000e+03
2.900000e+03
2.900000e+03
2.900000e+03
2.900000e+03
2.900000e+03
2.900000e+03
2.900000e+03
2.900000e+03
2.900000e+03

new2.txt

    0
  100
  200
    1
  101
  201
    2
  102
  202
    3
  103
  203
    4
  104
  204

I want to create a new list from the base.txt values(velocities) that would correspond to ascending order of second file.(0,1,2,3,4,5,..) My code so far

import itertools
from operator import itemgetter

vel = [line.strip() for line in open("base.txt", 'r')]
ind = [line.strip() for line in open("new2.txt", 'r')]

print type(vel)
print type(ind)

adict = dict(itertools.izip(ind,vel))

newlist = sorted(adict, key=itemgetter(ind))

My idea was to read files as lists,create dictionary and then try to sort out the values,but this code is not working. I got this

<type 'list'>
<type 'list'>
Traceback (most recent call last):
  File "m1.py", line 11, in <module>
    newlist = sorted(adict, key=itemgetter(ind))
TypeError: string indices must be integers, not list

The files are here http://pastebin.com/he1RuSnv

http://pastebin.com/VfXZB4W3

When I try solution of CPanda,I got

2.900000e+03 0
2.900000e+03 1
2.900000e+03 10
2.900000e+03 100
2.900000e+03 1000
2.900000e+03 1001
2.900000e+03 1002
2.900000e+03 1003
2.900000e+03 1004
2.900000e+03 1005
2.900000e+03 1006
2.900000e+03 1007
2.900000e+03 1008
2.900000e+03 1009
2.900000e+03 101
2.900000e+03 1010
2.900000e+03 1011
2.900000e+03 1012

This is not what I want,Iwant second index to go 0,1,2,3,4,5 and so on...

Richard Rublev
  • 7,718
  • 16
  • 77
  • 121

3 Answers3

2

To solve the error, your last line, the one with sorted should be

newlist = [el[1] for el in sorted(adict.items())]

Sorted returns a list of key value tuples from the dict.

Then with the list comprehension you extract the ordered values into your newlist

You can also merge the last two lines into one:

newlist = [el[1] for el in sorted(itertools.izip(ind,vel))]
Francesco
  • 4,052
  • 2
  • 21
  • 29
1

Using a dictionary or an associative array in this case is not what you are looking for. A dictionary is orderless and should not be used when order matters.

I would use a different data structure like the one mentioned here.

Sort a Python dictionary by value

Community
  • 1
  • 1
1

Try this

import itertools

with open("base.txt") as fv, open("new2.txt", 'r') as fi:
    vel = (line.strip() for line in fv)
    ind = (int(line.strip()) for line in fi)
    z = itertools.izip(ind, vel) # sort according to ind
    # itertools.izip(vel, ind) # sort according to vel
    for i, v in sorted(z):
        print v,i

# interactive session
l1 = ['2.900000e+03',
      '2.900000e+03',
      '2.900000e+03',
      '2.900000e+03',
      '2.900000e+03',
      '2.900000e+03',
      '2.900000e+03',
      '2.900000e+03',
      '2.900000e+03',
      '2.900000e+03',
      '2.900000e+03',
      '2.900000e+03',
      '2.900000e+03',
      '2.900000e+03',
      '2.900000e+03'] # list(vel)
l2 = [0, 100, 200, 1, 101, 201, 2, 102, 202, 3, 103, 203, 4, 104, 204] # list(ind)
# result
2.900000e+03 0
2.900000e+03 1
2.900000e+03 2
2.900000e+03 3
2.900000e+03 4
2.900000e+03 100
2.900000e+03 101
2.900000e+03 102
2.900000e+03 103
2.900000e+03 104
2.900000e+03 200
2.900000e+03 201
2.900000e+03 202
2.900000e+03 203
2.900000e+03 204
  • Use generator expressions instead of lists for memory efficiency and speed.
  • Use context managers to automatically close open files

Please comment if it doesn't work for you.

C Panda
  • 3,297
  • 2
  • 11
  • 11