Meaning of list[-1] in Python - python

I have a piece of code here that is supposed to return the least common element in a list of elements, ordered by commonality:
def getSingle(arr):
from collections import Counter
c = Counter(arr)
return c.most_common()[-1] # return the least common one -> (key,amounts) tuple
arr1 = [5, 3, 4, 3, 5, 5, 3]
counter = getSingle(arr1)
print (counter[0])
My question is in the significance of the -1 in return c.most_common()[-1]. Changing this value to any other breaks the code as the least common element is no longer returned. So, what does the -1 mean in this context?

One of the neat features of Python lists is that you can index from the end of the list. You can do this by passing a negative number to []. It essentially treats len(array) as the 0th index. So, if you wanted the last element in array, you would call array[-1].
All your return c.most_common()[-1] statement does is call c.most_common and return the last value in the resulting list, which would give you the least common item in that list. Essentially, this line is equivalent to:
temp = c.most_common()
return temp[len(temp) - 1]

Related

How can I substitute a list by index in python?

I need to write a function that contains 3 input parameters:
A list called randome containing random integer numbers
A list called indexes that contains (non-negative) indexes of items that need substitution by the third parameter. It is possible that indexes contains non-existent indexes for source. Check if the index actually exists in source before you substitute. Perhaps using the len of randome?
A value new_value that we use to overwrite the items in source. Assign True as default value.
For example: substitution_function([1, 2, 3, 4, 5], [0, 2], True) must return this list: [True, 2, True, 4, 5]
Anyone have any ideas?
def substitution_function(randome, indexes, new_value=True):
result = []
for data in indexes:
if data <= len(source):
result.append(new_value)
else:
for i in range(len(source)):
result.append(source[i])
return result
But this code can be greatly improved
The way you started is strange, let's start from scratch. There is 2 ways
Replace with the given value, at the given indexes
def substitution_function(source, indexes, new_value=True):
for index in indexes:
if index < len(source):
source[index] = new_value
return source
Build a whole new list, and conditionally use original value or replacement one
# that solution is safe-proof to invalid index
def substitution_function(source, indexes, new_value=True):
result = []
indexes = set(indexes) # can be added in case of large list
for i, data in enumerate(source):
if i in indexes:
result.append(new_value)
else:
result.append(data)
return result
I think it's better to you read the Stack Overflow Guidelines 😎
def overwriteArr(arr, idxs, val):
for idx in idxs:
try:
arr[idx] = val
except:
pass
return arr
print(overwriteArr([1, 2, 3, 4, 5], [0, 2], True)) # [True, 2, True, 4, 5]
It runs for loop on randome with getting item's index by enumerate(). If index is in indexes it returns new_value to listcomp's list if it's not it returns item. The possible problem of spare indexes in indexes is solved by just not touching them at all.
def substitution_function(randome, indexes, new_value=True):
return [new_value if e in indexes else i for e,i in enumerate(randome)]

Why list indexing [-4:0] not working while [0:4] works?

If negative list indexing is starting from the end the list and let's say we have:
l = [1,2,3,4,5]
and l[0:3] and l[:3] returns same values while l[-3:0] returns an empty list and l[-3:] returns [3,4,5]
What is the logic behind not allowing list[-x:0] to return the list?
l[-3:0] tries to slice from 3 from behind towards 0 - that is the same as l[2:0] .. that slices nothing because the first value > second value.
l[-3:] can be read as l[-3:len(l)] - so l[2:5] which returns the slice.
You would need l[-3:0:-1] for that to work - but thats mind boggling slicing which I try to avoid. ( print( [1,2,3,4,5][-3:0:-1] --> [3, 2] ) because it also reverses the slice "orientation" to backwards instead of forwards
l[-3:] slices from 3 from behind till the end.
The full notation of slice in Python is the following:
s[start:end:step]
That being said it provides useful defaults for the values, as per the documentation:
Slice indices have useful defaults; an omitted first index defaults to
zero, an omitted second index defaults to the size of the string being
sliced.
So when you do something like:
s[1:]
under the hood this is done:
s[1:len(s)]
Note that in both cases step defaults to 1. In most languages when you want to access the last element of a list for example you do something like:
s[len(s) - 1]
Python negative indexing is a sort of syntactic sugar on that notation so :
l[-1] = l[len(l) - 1]
l[-2] = l[len(l) - 2]
...
Then when you do:
l[-3:]
this is done:
l[len(l)-3:len(l)]
So, instead of 0 you should use len(l) as the last index:
l = [1, 2, 3, 4, 5]
print(l[-3:len(l)])
Output
[3, 4, 5]
Note that l[-3:0] returns the empty list because len(l) - 3 > 0, i.e. the first index is greater than the second and step is 1.
Further
Understanding Python's slice notation
Well 0 in front works, but at last... won't work, same with this:
>>> l=[1,2,3,4,5]
>>> l[2:0]
[]
>>>
because python is thinking zero at the end...
So that's virtually equivalent to:
>>> l=[1,2,3,4,5]
>>> l[:0]
[]
>>>
since of course there is nothing before first element, if there was, that thing wouldn't be first element, it would be second.
Negative indexes operate from the end of the list.
Say if you want to get the last 3 items, you could do:
# Reversing and restoring the order
my_list = [1,2,3,4,5,6]
print(reversed(reversed(my_list)[:3]))
# Subtracting from the size
size = len(my_list)
print(my_list[size-3:])
But instead you can type
my_list[-3:]
Which in words would state get me the slice of the list starting from the third item at the end of the list
So you have to be aware of what your asking for.
# Slice from the x'th element at the end till the end of the list
my_list[-x:]
# Slice from the x'th element at the end till the y'th element at the end of the list
my_list[-x:-y]
# Slice from the x'th element at the end till the y'th element from the start of the list.
# Only valid if len(my_list) - y < x and y > 0
my_list[-x:y]

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]))

add item to list python

I would like to add an item to a list in python, I want to add the item at an index which is greater than the size of the list. This should cause the list to grow automatically.
For example with a list of 3 items, I would like to insert element at index 6. Is this possible in python without first having to reinitialize the list?
It seems Python will merely append to the list if you try to insert an item at index 6 in my example.
You could write a function which, given a list, an index, and an element, inserts the element in the list before the index if the index is in range (in which case this is equivalent to the built-in insert method) or extends the list by enough Nones to fill it out before tacking it on the end:
>>> def put(xs,i,e):
n = len(xs)
if i <= n:
xs.insert(i,e)
else:
xs.extend([None]*(i-n-1))
xs.append(e)
>>> xs = [1,2,3]
>>> put(xs,6,10)
>>> xs
[1, 2, 3, None, None, 10]
>>>

Array Indexing in Python

Beginner here, learning python, was wondering something.
This gives me the second element:
list = [1,2,3,4]
list.index(2)
2
But when i tried this:
list = [0] * 5
list[2] = [1,2,3,4]
list.index[4]
I get an error. Is there some way to pull the index of an element from an array, no matter what list it's placed into? I know it's possible with dictionaries:
info = {first:1,second:2,third:3}
for i in info.values:
print i
1
2
3
Is there something like that for lists?
The index method does not do what you expect. To get an item at an index, you must use the [] syntax:
>>> my_list = ['foo', 'bar', 'baz']
>>> my_list[1] # indices are zero-based
'bar'
index is used to get an index from an item:
>>> my_list.index('baz')
2
If you're asking whether there's any way to get index to recurse into sub-lists, the answer is no, because it would have to return something that you could then pass into [], and [] never goes into sub-lists.
list is an inbuilt function don't use it as variable name it is against the protocol instead use lst.
To access a element from a list use [ ] with index number of that element
lst = [1,2,3,4]
lst[0]
1
one more example of same
lst = [1,2,3,4]
lst[3]
4
Use (:) semicolon to access elements in series first index number before semicolon is Included & Excluded after semicolon
lst[0:3]
[1, 2, 3]
If index number before semicolon is not specified then all the numbers is included till the start of the list with respect to index number after semicolon
lst[:2]
[1, 2]
If index number after semicolon is not specified then all the numbers is included till the end of the list with respect to index number before semicolon
lst[1:]
[2, 3, 4]
If we give one more semicolon the specifield number will be treated as steps
lst[0:4:2]
[1, 3]
This is used to find the specific index number of a element
lst.index(3)
2
This is one of my favourite the pop function it pulls out the element on the bases of index provided more over it also remove that element from the main list
lst.pop(1)
2
Now see the main list the element is removed..:)
lst
[1, 3, 4]
For extracting even numbers from a given list use this, here i am taking new example for better understanding
lst = [1,1,2,3,4,44,45,56]
import numpy as np
lst = np.array(lst)
lst = lst[lst%2==0]
list(lst)
[2, 4, 44, 56]
For extracting odd numbers from a given list use this (Note where i have assingn 1 rather than 0)
lst = [1,1,2,3,4,44,45,56]
import numpy as np
lst = np.array(lst)
lst = lst[lst%2==1]
list(lst)
[1, 1, 3, 45]
Happy Learning...:)
In your second example, your list is going to look like this:
[0, 0, [1, 2, 3, 4], 0, 0]
There's therefore no element 4 in the list.
This is because when you set list[2], you are changing the third element, not updating further elements in the list.
If you want to replace a range of values in the list, use slicing notation, for example list[2:] (for 'every element from the third to the last').
More generally, the .index method operates on identities. So the following will work, because you're asking python where the particular list object you inserted goes in the list:
lst = [0]*5
lst2 = [1,2,3,4]
lst[2] = lst2
lst.index(lst2) # 2
The answer to your question is no, but you have some other issues with your code.
First, do not use list as a variable name, because its also the name of the built-in function list.
Secondly, list.index[4] is different than list.index(4); both will give errors in your case, but they are two different operations.
If you want to pull the index of a particular element then index function will help. However, enumerate will do similar to the dictionary example,
>>> l=['first','second','third']
>>> for index,element in enumerate(l):
... print index,element
...
output
0 first
1 second
2 third

Categories

Resources