Comparing Two Lists to Find Bigger List - python

I have two lists and need to compare them by their largest element, if that is tied, their 2nd largest element, and if that is tied, 3rd largest etc iterating to the entire array.
For example:
list1= [0,2,3,6,12]
list2= [1,2,3,6,12]
list3= [1,4,5,8,12]
list4= [1,4,5,9,12]
So list4 > list3 > list2 > list1.
I wrote a function that accomplishes this:
def compare(x,y):
if sorted(x)==sorted(y):
return "Tie"
for index in range(len(x)-1,-1,-1):
if sorted(x)[index]>sorted(y)[index]:
return x
elif sorted(x)[index]<sorted(y)[index]:
return y
I was wondering if there was a much neater and more efficient way of writing the function because it doesn't seem very Pythonic.
Edit: comparing lists by using "<" and ">" will sort the lists from the smallest index to largest index, not largest index to smallest index. Reversed would make ">" and "<" the simplest solutions.

How about this?
>>> list1= [0,2,3,6,12]
>>> list2= [1,2,3,6,12]
>>> list3= [1,4,5,8,12]
>>> list4= [1,4,5,9,12]
>>> def sort_lists_by_maxes(*lists):
return sorted(lists, key=lambda x: sorted(x, reverse=True), reverse=True)
>>> sort_lists_by_maxes(list1, list2, list3, list4)
[[1, 4, 5, 9, 12], [1, 4, 5, 8, 12], [1, 2, 3, 6, 12], [0, 2, 3, 6, 12]]
The lists are compared by their individually sorted values, and you can feed as many lists as you would like into the function as arguments.

sorted of sorted is good, but I'm partial to:
#!/usr/local/cpython-3.3/bin/python
list1 = [0, 2, 3, 6, 12]
list2 = [1, 2, 3, 6, 12]
list3 = [1, 4, 5, 8, 12]
list4 = [1, 4, 5, 9, 12]
metalist = [ list1, list2, list3, list4 ]
for sublist in metalist:
sublist.sort(reverse=True)
metalist.sort(reverse=True)
print(metalist)
It should be faster and take less memory. It's also more clear to novices.

Related

Try To Print Map as str/list/join without succeess

def intersection(list_1, list_2):
return map(lambda list0 : list(dict.fromkeys(list0)), [x for x in list_1 if x in list_2 ])
print(intersection([5, 5, 6, 6, 7, 7], [1, 5, 9, 5, 6]))
In lambda the func that deletes duplicate and in [ ] the list (from list comprehension) the transfered to the func by map.
When I try to turn it into a list / str / join this error accourced.
What can I do and why is this happening ?
I added one example run that suppose to print [5,6] but returns error.
Be noticed that the list itself ([ ]) reutrns alone: [5, 5, 6, 6] because of the duplicates in the original lists.
Also if I change the code from one line to block og code it works:
def intersection(list_1, list_2):
my_list = [x for x in list_1 if x in list_2]
small_func = lambda list0 : list(set(list0))
return small_func(my_list)
returns: [5,6]
Thanks !
I don't think you need map here. Your idea was right to convert to dictionary and than convert back to list but you have to do that only once.
def intersection(list_1, list_2):
return list(dict.fromkeys([x for x in list_1 if x in list_2]))
print (intersection([5, 5, 6, 6, 7, 7], [1, 5, 9, 5, 6]))

Ordered list from elements of a 2 dimensional list?

I have a 2 dimensional list. Example:
list = [[1,4,7], [2,5,8], [3,6,9]]
I need to make a new list whose elements are the elements of each sub-element preserving the order.
Example:
final_list = [1,2,3,4,5,6,7,8,9]
Q: The new list must take the first element of each list first, then the
second, and so on..
A:
You can use zip and a list comprehension.
list_1 = [1,4,7]
list_2 = [2,5,8]
list_3 = [3,6,9]
print([x for lst in zip(list_1, list_2, list_3) for x in lst])
# outputs > [1, 2, 3, 4, 5, 6, 7, 8, 9]
For your new list, you could do the same, but first unpack the list with a *
new_list = [[1,4,7], [2,5,8], [3,6,9]]
print([x for lst in zip(*new_list) for x in lst])
# outputs > [1, 2, 3, 4, 5, 6, 7, 8, 9]
first transpose the list matrix with zip then chaining all the inner list together with itertools
also rename variable list to lst, not a good practice to use builtin list as variable name
import itertools
lst = [[1,4,7], [2,5,8], [3,6,9]]
final_list = list(itertools.chain.from_iterable(zip(*lst)))
# final_list = [1, 2, 3, 4, 5, 6, 7, 8, 9]

Splicing a list at different intervals based on a value of a list in python

Instead of posting a long winded example, I will post a simplified idea of what I want to achieve.
This is a bit of code that doesn't work, but it is what I want to do. I would like to take the last 4 values of list1 and append them to a new list, then take the last 3 values and append them to the same list and then take the last 2 values and append them to that same list.
Basically print list2 would give [[1,2,3,4],[2,3,4],[3,4]]
Here is the code;
def test():
list1 = range(5)
list2 = []
q=[2,4,6]
j=0
for j in range(len(q)):
list2.append(list1[(q[j]*0.5):])
print list2
Thank you
You can use the following code snippet
list2 = [list1[-i:] for i in range(4,1,-1)]
For example
>>> list1 = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> list2 = [list1[-i:] for i in range(4,1,-1)]
>>> list2
[[6, 7, 8, 9], [7, 8, 9], [8, 9]]
Your code does something different, but after your description, this should do it:
for l in range(len(list1), 0, -1):
list2.append(list1[-l:])

how do I concatenate 3 lists using a list comprehension?

In python, how do I concatenate 3 lists using a list comprehension?
Have:
list1 = [1,2,3,4]
list2 = [5,6,7,8]
list3 = [9,10,11,12]
Want:
allList = [1,2,3,4,5,6,7,8,9,10,11,12]
I tried using a list comprehension, but I'm not very good at them yet. These are what I have tried:
allList = [n for n in list1 for n in list2 for n in list3 ]
this was a bad idea, obviously and yielded len(list1)*len(list2)*len(list3) worth of values. Oops. So I tried this:
allList = [n for n in list1, list2, list3]
but that gave me allList = [list1, list 2, list3] (3 lists of lists)
I know you can concatenate using the + operator (as in x = list1 + list2 + list3)but how do you do this using a simple list comprehension?
There is a similar question here: Concatenate 3 lists of words , but that's for C#.
A better solution is to use itertools.chain instead of addition. That way, instead of creating the intermediate list list1 + list2, and then another intermediate list list1 + list2 + list3, you just create the final list with no intermediates:
allList = [x for x in itertools.chain(list1, list2, list3)]
However, an empty list comprehension like this is pretty silly; just use the list function to turn any arbitrary iterable into a list:
allList = list(itertools.chain(list1, list2, list3))
Or, even better… if the only reason you need this is to loop over it, just leave it as an iterator:
for thing in itertools.chain(list1, list2, list3):
do_stuff(thing)
While we're at it, the "similar question" you linked to is actually a very different, and more complicated, question. But, because itertools is so cool, it's still a one-liner in Python:
itertools.product(list1, list2, list3)
Or, if you want to print it out in the format specified by that question:
print('\n'.join(map(' '.join, itertools.product(list1, list2, list3))))
Here are some options:
>>> sum([list1, list2, list3], [])
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
>>> list1 + list2 + list3
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
With comprehension: (it's really not necessary)
>>> [x for x in sum([list1, list2, list3], [])]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
You can do allList = list1 + list2 + list3 instead of allList = [x for x in list1 + list2 + list3]
If you put the lists that you want to concatenate in a list literal, you can write a nested for loop in the list comprehension to loop over all elements.
allList = [n for l in [list1, list2, list3] for n in l]
This solution does not need any extra imports or other functions to concatenate the lists.
As an alternative to all of the other options, you could also just splat them all into a new list for comprehension (if you don't explicitly require a comprehension to generate the concatenated list):
>>> list1 = [1, 2, 3, 4]
>>> list2 = [5, 6, 7, 8]
>>> list3 = [9, 10, 11, 12]
>>> allList = [*list1, *list2, *list3]
>>> allList
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
I couldn't come up with any reason why the new list would need deriving from a comprehension explicitly since you could just nest this inside a comprehension if desired, e.g. if you had other logic to run on the merged list:
>>> [val + 3 for val in [*list1, *list2, *list3]]
[4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
If performance is a big deal, you can also just make the splatted list a generator function instead:
>>> [val + 3 for val in (*list1, *list2, *list3)]
[4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
Simply do list1 + list2 + list3
>>> list1 = [1,2,3,4]
>>> list2 = [5,6,7,8]
>>> list3 = [9,10,11,12]
>>>
>>> list1 + list2 + list3
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
If you want to remove duplicates, run below code:
>>> list(set(list1 + list2 + list3))
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]

Comparing lists in Python

Say I have list1 = [1,2,3,4] and list2 = [5,6,7,8]. How would I compare the first element, 1, in list1 with the first element, 5, in list2? And 2 with 6, 3 with 7, and so on.
I'm trying to use a for loop for this, but I'm not sure how to do it. I understand that doing for x in list1 just checks an element x to all elements in list1, but I don't know how to do it when comparing two lists the way I described.
You can traverse both lists simultaneously using zip:
for (x, y) in zip(list1, list2): do_something
The 'zip' function gives you [(1,5), (2,6), (3,7), (4,8)], so in loop iteration N you get the Nth element of each list.
The default comparison operators compare lists in lexicographical order. So you can say things like:
>>> [1, 2, 3, 4] < [5, 6, 7, 8]
True
If instead you want to compute the elementwise comparison, you can use map and cmp (or any other operator:
>>> map(cmp, [1, 2, 3, 4], [5, 6, 7, 8])
[-1, -1, -1, -1]
If your result is going to be a new list, then you can use a list comprehension:
new_list = [ some_function(i, j) for i, j in zip(list1, list2) ]
Here's a real example of the above code:
>>> list1 = [1, 2, 3, 4]
>>> list2 = [1, 3, 4, 4]
>>> like_nums = [ i == j for i, j in zip(list1, list2) ]
>>> print like_nums
[True, False, False, True]
This will make a list of bools that show whether items of the same index in two lists are equal to each other.
Furthermore, if you use the zip function, there is a way to unzip the result when you are done operating on it. Here's how:
>>> list1 = [1, 2, 3, 4]
>>> list2 = [1, 3, 4, 4]
>>> new_list = zip(list1, list2) # zip
>>> print new_list
[(1, 1), (2, 3), (3, 4), (4, 4)]
>>> newlist1, newlist2 = zip(*new_list) # unzip
>>> print list(newlist1)
[1, 2, 3, 4]
>>> print list(newlist2)
[1, 3, 4, 5]
This could be useful if you need to modify the original lists, while also comparing the elements of the same index in some way.

Categories