简体   繁体   中英

Python sorting tuples by first and second element

I am using a python script that takes input from STDIN. I have no access as to how the data is sorted in the input.

Each line in the input has the following form:

(Int,Int)  \t  Int

Now when the data comes in it's sorted by the tuples, but not properly. So it looks something like this:

(0,1)     5
(0,10)    2
(0,2)     3
(1,8)     7
(1,82)    5
(1,9)     4

Now this is wrong since I'd like them sorted by first and then by the second element in the tuple - so it should look like this:

(0,1)     5
(0,2)     3
(0,10)    2
(1,8)     7
(1,9)     4
(1,82)    5

My problem is that the lines are coming through one by one. So I have to sort them after they come in.

I tried to allocate an array and when a new tuple comes in - I tried to insert it in its proper place, but that seems to be contradicting Python's notion of arrays.

How would I approach this problem?

Perhaps, this will better suite you:

with open('stuff.txt', 'r') as f:
    store = []
    for line in f:
        tup, num = line.split()
        tup = tuple(map(int, tup[1:-1].split(',')))
        num = int(num)

        store.append((tup, num))
    print sorted(store)

Stuff.txt :

(0,1)     5
(0,10)    2
(0,2)     3
(1,8)     7
(1,82)    5
(1,9)     4

And the output, as you would expect:

[(('0', '1'), 5), (('0', '2'), 3), (('0', '10'), 2), (('1', '8'), 7), (('1', '9'), 4), (('1', '82'), 5)]

Note - Avoid using eval . Do the type casting like GamesBraniac did. You can do something like this

with open("input_file.txt") as input_file:
    sorted_array = []
    for line in input_file:
        tup, val = map(eval, line.split())
        # Verify the input data
        try:
            assert type(tup) == tuple
            assert type(val) == int
            sorted_array.append([tup, val])
        except:
            print "Invalid input"


sorted_array.sort()
print sorted_array

Gives output

[[(0, 1), 5], [(0, 2), 3], [(0, 10), 2], [(1, 8), 7], [(1, 9), 4], [(1, 82), 5]]

For pretty output, you could do

>>>for tup, val in sorted_array:
...    print "{0}\t{1}".format(tup, val)
>>> 
(0, 1)  5
(0, 2)  3
(0, 10) 2
(1, 8)  7
(1, 9)  4
(1, 82) 5
>>> 

line.split('\\t')[0] will give you the items to the left of the tab. ast.literal_eval() will turn that into 2-integer tuples. Use itertools.groupby() to remove sorting by the first element, since it comes in sorted. Sort the second element of the group in order to sort by the second element. Append the new sorted groups to the existing data.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM