Python - How to find an item in a list - python

...and compare it with another list to get the same item in the same index/position.
Eg.
a = [1, 2, 3, 4, 5]
b = [a, b, c, d, e]
I want the highest number in list a so:
5
And then, I compare it with list b to get the item, which is on the same position as the highest number in list a:
e
I apologize for the poorly worded question but this is the best I can explain it.

One-liner: b[a.index(max(a))]
However, this makes two pass through the list, i.e. first with max(a), and second with a.index.
The snippet below makes only one pass:
max_index, max_value = max(enumerate(a), key=lambda p: p[1])
print(b[max_index])

python has this great built in array function called index that will take care of what you need.
in your example: x = b[a.index(5)] which takes a and gets the index of 5 (which is 4) and then assigns the item in b at that index to the variable x so that you can do whatever evaluations you may need.

Related

Get indices of top N values from list in the order of the values

I have a list like a=[3,5,7,12,4,1,5] and need to get the indices of the top K(=3) elements of this list, in the order of the elements. So in this case, result should be
[3,2,1]
since top 3 elements are 12, 7, 5 (last one is tie so first index is returned).
What is the simplest way to get this?
As this is tagged numpy, you can use numpy.argsort on the opposite values (for reverse sorting), then slice to get the K desired values:
a = np.array([3,5,7,12,4,18,1,5,18])
K = 3
out = np.argsort(-a)[:K]
output: array([3, 2, 1])
If you want the indices in order of the original array but not necessarily sorted themselves in order of the values, you can also use numpy.argpartition:
out = np.argpartition(a, K)[-K:]
I assume you mean 3,2,1 right?
[a.index(i) for i in sorted(a)[:3:-1]]
Personally, I would create a sorted list through the sorted method, then compare the first K values with the .index attribute of a. This will yield you your desired result.
K = 3 #Number of elemens
a = [3,5,7,12,4,1,5]
a_sorted = sorted(a,reverse=True)
b = [a.index(v) for v in a_sorted[:K]]
print(b)
>>> [3, 2, 1]

How to get n element from the python list?

I have the following arrays:
a=[1,2,3,4]
b=['car','apple','orange']
I'm trying to iterate through arrays using:
for first,second in zip(a,b):
print(first,second)
But it prints all of the values at at time. How can I print 1st element from a array and 1st element from b array and so on?
You can use the [] operator to print the nth element of any array.
We can use a for loop to achieve a constant n value like this:
for i in range(3):
print(a[i], b[i])
Replace 3 with the length of both arrays, as the length should be the same.
You have two lists of differing lengths. Therefore, in order to access the values in pairs you could (probably should) use the zip() function.
If you don't want to use zip() then you need to start by determining the length of the shortest list then you can safely iterate over them. Something like this:
a = [1, 2, 3, 4]
b = ['car', 'apple', 'orange']
for k in range(len(min(a, b, key=len))):
print(a[k], b[k])
Output:
1 car
2 apple
3 orange

In Python, is there a build-in function to get the values (in list) between two given ones?

Is there a built-in function to get the values (in list) between two given ones?
For example, let LIST be a Python list defined as:
LIST=[value_1, value_2, value_3,...,value_n]
how to find the elements between (for example) value_p and value_k, where p is less than k, and p, k both belong to the interval [0,n]
Using list slicing
arr = [1,2,3,4,5,6,7]
arr[3:6]
output:
[4, 5, 6]
here 3 is p
and 6 is k

Recursively multiply all values in an array Python

I've had a look through the forums and can't find anything to do with multiplying all elements in an array recursively.
I've created the following code that almost does what I want. The goal is to use no loops and only recursion.
Here's the code:
def multAll(k,A):
multAllAux(k,A)
return A[:]
def multAllAux(k,A):
B = [0]
if A == []:
return 0
else:
B[0] = (A[0] * k)
B.append(multAllAux(k,A[1:]))
return B
print(multAllAux(10, [5,12,31,7,25] ))
The current output is:
[50, [120, [310, [70, [250, 0]]]]]
However, it should be:
[50,120,310,70,250]
I know I am close, but I am at a complete loss at this point. The restrictions of no loops and solely recursion has left me boggled!
Your multAllAux function returns a list. If you append a list to another list, you get this nested list kind of structure that you are getting right now.
If you instead use the "extend" function; it will work as expected.
>>> a = [1, 2, 3]
>>> a.extend([4, 5])
>>> a
[1, 2, 3, 4, 5]
extend takes the elements from a second list and adds them to the first list, instead of adding the second list itself which is what append does!
Your function also returns a zero at the end of the list, which you don't need. You can try this:
def mult(k, A: list) -> list:
return [k * A[0]] + mult(k, A[1:]) if A else []
The problem is here:
B.append(multAllAux(k,A[1:])))
What .append(..) does is it takes the argument, considers it as a single element and adds that element to the end of the list. What you want is to concatenate to the list (ie the item being added should be seen as a list of elements rather than one single element).
You can say something like: B = B + multAllAux(..) or just use +=
B += multAllAux(...)
BTW, if you wanted to multiply a single number to a list, there is a very similar construct: map(..). Note that this behaves slightly differently depending on whether you're using Py2 or Py3.
print(map(lambda x: x * 10, [5,12,31,7,25]))

In-place modification of Python lists

I am trying to perform in-place modification of a list of list on the level of the primary list. However, when I try to modify the iterating variable (row in the example below), it appears to create a new pointer to it rather than modifying it.
Smallest example of my problem.
c = [1,2,3]
for x in c:
x = x + 3
print(c) #returns [1,2,3], expected [4,5,6]
The above example is a trivial example of my problem. Is there a way to modify x elementwise, in-place and have the changes appear in C?
Less trivial example of my problem. I am switching all 0's to 1's and vice-versa.
A = [[1,1,0],
[1,0,1],
[0,0,0]]
for row in A:
row = list(map(lambda val: 1 - val, row))
print(A)
Expected
A = [[0,0,1],
[0,1,0],
[1,1,1]]
Returned
A = [[1,1,0],
[1,0,1],
[0,0,0]]
update:
Great answers so far. I am interested how the iterating variable (row in the second example) is linked to the iterable variable (A in the second example).
If I do the following, which reverses each sublist of A, it works perfectly.
Why does the following example, where I modify the iterating variable works but the above examples do not?
A = [[1,1,0],
[1,0,1],
[0,0,0]]
for row in A:
row.reverse()
print(A)
#returns, as expected
A = [[0, 1, 1],
[1, 0, 1],
[0, 0, 0]]
I found this in the docs: https://docs.python.org/3/tutorial/controlflow.html#for
Python’s for statement iterates over the items of any sequence (a list
or a string), in the order that they appear in the sequence.
If you need to modify the sequence you are iterating over while inside
the loop (for example to duplicate selected items), it is recommended
that you first make a copy. Iterating over a sequence does not
implicitly make a copy.
I was wrong in my first response, when iterating through a list it returns the actual items in that list. However, it seems they cannot be edited directly while they are being iterated through. This is why iterating through the integers the length of the list works.
As for why the .reverse() function works, I think it's because it is affecting a list instead of a value. I tried to use similar built in functions on nonlist datatypes like .replace() on strings and it had no effect.
All of the other list functions I tried worked: .append(), .remove(), and .reverse() as you showed. I'm not sure why this is, but I hope it clears up what you can do in for loops a bit more.
Answer to old question below:
The way you are using the for loops doesn't affect the actual list, just the temporary variable that is iterating through the list. There are a few ways you can fix this. Instead of iterating through each element you can can count up to the length of the list and modify the list directly.
c = [1,2,3]
for n in range(len(c)):
c[n] += 3
print(c)
You can also use the enumerate() function to iterate through both a counter and list items.
c = [1,2,3]
for n, x in enumerate(c):
c[n] = x + 3
print(c)
In this case, n is a counter and x is the item in the list.
Finally, you can use list comprehension to generate a new list with desired differences in one line.
c = [1, 2, 3]
d = [x + 3 for x in c]
print(d)
The usual way to poke values into an existing list in Python is to use enumerate which lets you iterate over both the indices and the values at once -- then use the indices to manipulate the list:
c = [1,2,3]
for index, value in enumerate(c):
c[index] = value + 3
For your second example you'd do almost the same:
A = [[1,1,0],
[1,0,1],
[0,0,0]]
for row in A:
for index, val in row:
row[index] = 0 if val > 0 else 1
In the second example the list objects in A become the loop variable row -- and since you're only mutating them (not assigning to them) you don't need enumerate and the index
If you want to keep it consice without creating an additional variable, you could also do:
c = [1,2,3]
print(id(c))
c[:] = [i+3 for i in c]
print(c, id(c))
Output:
2881750110600
[4, 5, 6] 2881750110600
Using list comprehension here also will work:
A = [[1,1,0],
[1,0,1],
[0,0,0]]
A = [[0 if x > 0 else 1 for x in row] for row in A]
print(A)
Output:
[[0, 0, 1],
[0, 1, 0],
[1, 1, 1]]

Categories

Resources