Make a list with non-decreasing order elements of a list in Python - python-3.x

I have a list a = [2,2,1,3,4,1] .
I want to make a new list c with the non-decreasing elements lists of list a.
That means my expected form is -
c = [[2,2],[1,3,4],[1]]
Here is my code:
>>> c = []
>>> for x in a:
... xx = a[0]
... if xx > x:
... b = a[:x]
... c.append(b)
... a = a[x:]
but my output is:
>>> c
[[2], [2]]
How can i make a list with all non-decreasing part of list a?

You can initialise the first entry of c with [a[0]] and then either append the current value from a to the end of the current list in c if it is >= the previous value, otherwise append a new list containing that value to c:
a = [2,2,1,3,4,1]
c = [[a[0]]]
last = a[0]
for x in a[1:]:
if x >= last:
c[-1].append(x)
else:
c.append([x])
last = x
print(c)
Output:
[[2, 2], [1, 3, 4], [1]]

If I understand what you are after correctly then what you want is to split the list every time the number decreases. If so then this should do what you need
c = []
previous_element = a[0]
sub_list = [previous_element]
for element in a[1:]:
if previous_element > element:
c.append(sub_list)
sub_list = []
previous_element = element
sub_list.append(previous_element)
c.append(sub_list)
Output:
In [1]: c
Out[2]: [[2, 2], [1, 3, 4], [1]]
There is possibly a clearer way to right the above, but it's pre coffee for me ;)
Also note that this code assumes that a will contain at least one item, if that is not always the case then you will need to either add an if statement around this, or re-structure the loop in a more while loop

Related

How to convert list of strings to integer indexes?

I have a list like this:
lst = [['ab', 'bc', 'cd'], ['dg', 'ab']]
I want to build a string indexer and convert it into:
lst_converted = [[1,2,3], [4,1]]
Do some processing on the converted list and then if the output is [[3], [2]]
lst_output = [['cd'], ['ab']]
Here,
'ab' = 1
'bc' = 2
'cd' = 3
'dg' = 4
Strings can be arbitrary and not necessarily characters. How to do this?
Use a list comprehension along with a dictionary to map the string literals to integer values:
d = {}
d['ab'] = 1
d['bc'] = 2
d['cd'] = 3
d['dg'] = 4
lst = [['ab', 'bc', 'cd'], ['dg', 'ab']]
lst_converted = [[d[y] for y in x] for x in lst]
print(lst_converted) # [[1, 2, 3], [4, 1]]

How to multiply 2 input lists in python

Please help me understand how to code the following task in Python using input
Programming challenge description:
Write a short Python program that takes two arrays a and b of length n
storing int values, and returns the dot product of a and b. That is, it returns
an array c of length n such that c[i] = a[i] · b[i], for i = 0,...,n−1.
Test Input:
List1's input ==> 1 2 3
List2's input ==> 2 3 4
Expected Output: 2 6 12
Note that the dot product is defined in mathematics to be the sum of the elements of the vector c you want to build.
That said, here is a possibiliy using zip:
c = [x * y for x, y in zip(a, b)]
And the mathematical dot product would be:
sum(x * y for x, y in zip(a, b))
If the lists are read from the keyboard, they will be read as string, you have to convert them before applying the code above.
For instance:
a = [int(s) for s in input().split(",")]
b = [int(s) for s in input().split(",")]
c = [x * y for x, y in zip(a, b)]
Using for loops and appending
list_c = []
for a, b in zip(list_a, list_b):
list_c.append(a*b)
And now the same, but in the more compact list comprehension syntax
list_c = [a*b for a, b in zip(list_a, list_b)]
From iPython
>>> list_a = [1, 2, 3]
>>> list_b = [2, 3, 4]
>>> list_c = [a*b for a, b in zip(list_a, list_b)]
>>> list_c
[2, 6, 12]
The zip function packs the lists together, element-by-element:
>>> list(zip(list_a, list_b))
[(1, 2), (2, 3), (3, 4)]
And we use tuple unpacking to access the elements of each tuple.
From fetching the input and using map & lambda functions to provide the result. If you may want to print the result with spaces between (not as list), use the last line
list1, list2 = [], []
list1 = list(map(int, input().rstrip().split()))
list2 = list(map(int, input().rstrip().split()))
result_list = list(map(lambda x,y : x*y, list1, list2))
print(*result_list)
I came out with two solutions. Both or them are the ones that are expected in a Python introductory course:
#OPTION 1: We use the concatenation operator between lists.
def dot_product_noappend(list_a, list_b):
list_c = []
for i in range(len(list_a)):
list_c = list_c + [list_a[i]*list_b[i]]
return list_c
print(dot_product_noappend([1,2,3],[4,5,6])) #FUNCTION CALL TO SEE RESULT ON SCREEN
#OPTION 2: we use the append method
def dot_product_append(list_a, list_b):
list_c = []
for i in range(len(list_a)):
list_c.append(list_a[i]*list_b[i])
return list_c
print(dot_product_append([1,2,3],[4,5,6])) #FUNCTION CALL TO SEE RESULT ON SCREEN
Just note that the first method requires that you cast the product of integers to be a list before you can concatenate it to list_c. You do that by using braces ([[list_a[i]*list_b[i]] instead of list_a[i]*list_b[i]). Also note that braces are not necessary in the last method, because the append method does not require to pass a list as parameter.
I have added the two function calls with the values you provided, for you to see that it returns the correct result. Choose whatever function you like the most.

How can I build new list from the old one in Python adding two new elements at a time?

I work with a tree and my code looks like this
new_lst = [x.left for x in lst if x.left] + [x.right for x in lst if x.right]
Is there an elegant way to rewrite it with just one list comprehension?
Thank you!
You should iterate over the tuple (x.left, x.right) inside the list comprehension.
>>> from collections import namedtuple
>>> Tree = namedtuple('Tree', ['left', 'right'])
>>> L = [Tree(1,2), Tree(0,3), Tree(4,0)]
(for the example, left and right are numbers; they should obviously be subtrees or None).
Your version:
>>> [x.left for x in L if x.left] + [x.right for x in L if x.right]
[1, 4, 2, 3]
In one pass:
>>> [t for x in L for t in (x.left, x.right) if t]
[1, 2, 3, 4]
Note that the order is different.

Compare unique string values between two lists and get the count of matched values in python

I have two lists with some items in common and some not. I would like to compare the two lists and get the count of items that matched.
list1 = ['apple','orange','mango','cherry','banana','kiwi','tomato','avocado']
list2 = ['orange','avocado','kiwi','mango','grape','lemon','tomato']
Pls advice how to do this in python
Use Counters and dictionary comprehension.
list1 = ['apple','orange','mango','cherry','banana','kiwi','tomato','avocado']
list2 = ['orange','avocado','kiwi','mango','grape','lemon','tomato']
c1 = Counter(list1)
c2 = Counter(list2)
matching = {k: c1[k]+c2[k] for k in c1.keys() if k in c2}
print(matching)
print('{} items were in both lists'.format(len(macthing))
Output:
{'avocado': 2, 'orange': 2, 'tomato': 2, 'mango': 2, 'kiwi': 2}
5 items were in both lists
I think you can use set.intersection within a comprehension like this example:
list1 = ['apple','orange','mango','cherry','banana','kiwi','tomato','avocado']
list2 = ['orange','avocado','kiwi','mango','grape','lemon','tomato']
result = {elm: list1.count(elm) + list2.count(elm) for elm in set.intersection(set(list1), set(list2))}
Output:
{'kiwi': 2, 'avocado': 2, 'orange': 2, 'tomato': 2, 'mango': 2}

Creating a new list from a list of tuples in python

I have a list of tuples
a = [(1,'a'),(2,'b'),(3,'c'),(4,'d')]
and another list
b = [1,2,4]
Now, using lists a and b I want to generate a list c which contains the corresponding elements of a which are present in list b.
That means c should be
c = ['a','b','d']
how can I do that?
Nested loops:
c = []
for b_number in b:
for a_number, a_letter in a:
if b_number == a_number:
c.append(a_letter)
break
or a less efficient (no break) list comprehension:
c = [a_letter for a_number, a_letter in a for b_number in b if b_number == a_number]
Assuming the numbers in a are unique it will be easier to use a dictionary:
a = {1: 'a', 2: 'b', 3: 'c', 4: 'd'}
b = [1, 2, 4]
c = [a[b_number] for b_number in b]

Resources