7

Update: The list are filled with strings I edited the list to show this

I have 3 different list such as

Section = [('1', '1.1', '1.2'), ('1', '2', '2.2', '3'), ('1', '1.2', '3.2', '3.5')] 
Page = [('1', '1', '3'), ('1', '2', '2', '2'), ('1', '2', '3', '5')]
Titles = [('General', 'Info', 'Titles'), ('More', 'Info', 'Section', 'Here'), ('Another', 'List', 'Of', 'Strings')]

I want to combine them such as

Combined_List = [('1', '1.1', '1.2'), ('1', '2', '2.2', '3'), ('1', '1.2', '3.2', '3.5'),
                 ('1', '1', '3'), ('1', '2', '2', '2'), ('1', '2', '3', '5'),  
                 ('General', 'Info', 'Titles'), ('More', 'Info', 'Section', 'Here'), ('Another', 'List', 'Of', 'Strings')]

Or any other form that allows me to then sort them by the numbers in the list titled sections.

In this case it would be

  Sorted_list = [('1', '1', '1', '1.1', '1.2', '1.2', '2', '2.2', '3', '3.2', '3.5'), 
                 ('1', '1', '1', '1', '3', '2', '2', '2', '2', '3', '5'),
                 ('General', 'More', 'Another', 'Info', 'Titles', 'List', 'Info', 'Section', 'Here', 'Of', 'Strings')

I need it like this so I can eventually export a sorted list by Section into excel. If you can think of a better way to display/format please do share!

SparkAndShine
  • 17,001
  • 22
  • 90
  • 134
Jstuff
  • 1,266
  • 2
  • 16
  • 27

3 Answers3

2

You can do:

from itertools import chain

tuples = zip(map(float, list(chain(*Section))), 
             list(chain(*Page)), 
             list(chain(*Title)))

zip(*sorted(tuples, key=lambda x: x[0]))

Out[232]:
[(1.0, 1.0, 1.0, 1.1, 1.2, 1.2, 2.0, 2.2, 3.0, 3.2, 3.5),
 ('1', '1', '1', '1', '3', '2', '2', '2', '2', '3', '5'),
 ('General',
  'More',
  'Another',
  'Info',
  'Titles',
  'List',
  'Info',
  'Section',
  'Here',
  'Of',
  'Strings')]

Here you first unnest your three list (what list(chain(*L)) does) and pack them in tuples with zip. Tip "tuples" to see how it looks.

Then on the second line of code you can apply the sorting according to the element of the tuple you want. And you unpack the result.

Colonel Beauvel
  • 30,423
  • 11
  • 47
  • 87
  • I forgot to inlcude in the original code that the list are filled with strings. I have updated the post to show this. I tried your method and then printed the value of tuples and the second line in the code. They returned and respectively. These are locations in memory correct? Did this happen because they are actually strings? – Jstuff Jun 02 '16 at 13:43
  • I updated my answer to take into account the fact you have strings. – Colonel Beauvel Jun 02 '16 at 13:54
  • When I print the list I still get . Not sure why... – Jstuff Jun 02 '16 at 14:02
  • I guess it is due to python version ...what returns `tuples` first? A list? try to wrap the zip with `list()`. – Colonel Beauvel Jun 02 '16 at 14:26
  • Yes in Python 3 zip returns an iterator. – ayhan Jun 02 '16 at 14:27
2

Try this,

Section = [('1', '1.1', '1.2'), ('1', '2', '2.2', '3'), ('1', '1.2', '3.2', '3.5')] 
Page = [('1', '1', '3'), ('1', '2', '2', '2'), ('1', '2', '3', '5')]
Titles = [('General', 'Info', 'Titles'), ('More', 'Info', 'Section', 'Here'), ('Another', 'List', 'Of', 'Strings')]

# Flat a list of tuples into a list
l1 = [item for sublist in Section for item in sublist]
l2 = [item for sublist in Page for item in sublist]
l3 = [item for sublist in Titles for item in sublist]

# Python2, `zip` returns a list of tuples
#result = zip(*sorted(zip(l1, l2, l3), key=lambda x:float(x[0])))

# Python3, `zip` returns an iterator of tuples
result = list(zip(*sorted(zip(l1, l2, l3), key=lambda x:float(x[0]))))

print(result)
# Output
[   ('1', '1', '1', '1.1', '1.2', '1.2', '2', '2.2', '3', '3.2', '3.5'), 
    ('1', '1', '1', '1', '3', '2', '2', '2', '2', '3', '5'), 
    ('General', 'More', 'Another', 'Info', 'Titles', 'List', 'Info', 'Section', 'Here', 'Of', 'Strings')]
SparkAndShine
  • 17,001
  • 22
  • 90
  • 134
  • When I print result it returns . Which is a location in memory, no? Why would it return this? – Jstuff Jun 02 '16 at 14:05
  • @Jstuff, since you use Python3, add `list` to the front of `zip(...)`. `zip` in Python3 returns an iterator. Check my edited answer. – SparkAndShine Jun 02 '16 at 14:10
  • 1
    Perfect, this is exactly what I was looking for! Quick question though. In the data I'm working with it has decimals to the second decimal place so 1.10, 1.11, etc and it sorted this as 1, 1.1, 1.10, 1.1, etc. Is there a way to tell python to sort it as 1.1, 1.2, ..., 1.9, 1.10, etc? – Jstuff Jun 02 '16 at 14:21
  • @Jstuff, good question. Split a number into the integer and decimal parts, use `zip` to pack them, sort them and integrate them. – SparkAndShine Jun 02 '16 at 14:31
  • Bear with me I'm still new to python. I tried doing l1_float = [float(i) for i in l1], but it drops the zero off of 1.10 so it sorts it has 1, 1.1, 1.1, 1.2 instead of 1, 1.1, 1.2, 1.10.0 Is there a better way to do this so it keeps the trailing zeros? Also, why do you float the value you pass into into lambda? – Jstuff Jun 02 '16 at 15:04
  • @Jstuff, I just posted a new question, [How do I sort a list of section numbers in Python?](http://stackoverflow.com/questions/37595703/how-do-i-sort-a-list-of-section-numbers-in-python). – SparkAndShine Jun 02 '16 at 15:12
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/113656/discussion-between-jstuff-and-sparkandshine). – Jstuff Jun 02 '16 at 15:51
-1

My approach. List comprehension and no need to import modules. I think its fast, and its very simple.

EDIT: I've added an unsorted approach and a sorted approach.

#Unsorted
newList =[
    [item for sublist in Section for item in sublist],
    [item for sublist in Page for item in sublist],
    [item for sublist in Titles for item in sublist]
    ]

print newList
#Output
#[[1, 1.1, 1.2, 1, 2, 2.2, 3, 1, 1.2, 3.2, 3.5], 
# [1, 1, 3, 1, 2, 2, 2, 1, 2, 3, 5], 
# ['General', 'Info', 'Titles', 'More', 'Info', 'Section', 'Here', 'Another', 'List', 'Of', 'Strings']]

#Sort first two lists afterwards, if desired
for i in range(2):
    newList[i].sort()

print newList
#Output
#[[1, 1, 1, 1.1, 1.2, 1.2, 2, 2.2, 3, 3.2, 3.5], 
# [1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 5], 
# ['General', 'Info', 'Titles', 'More', 'Info', 'Section', 'Here', 'Another', 'List', 'Of', 'Strings']]
Jeremy
  • 818
  • 6
  • 19
  • That's not OP's desired result since you sort the list independently. – SparkAndShine Jun 02 '16 at 13:41
  • @sparkandshine Ah, I see he said he wanted a form where it could be sorted afterwards. Thanks for the feedback. I'll edit my answer. – Jeremy Jun 02 '16 at 13:44
  • Perhaps I didn't make this clear, I only want to sort the list Section and the rest of the other two list should be sorted in the same order of the list Section after it is sorted. For example if after sorting Section the first few indices changed to 2, 4, 1. The other two list would need to change their indices to 2, 4, 1. – Jstuff Jun 02 '16 at 14:13