Can anyone please explain how to output the rightmost index from several most-same-values indexes in the list?
my function:
def last_index(xs,key):
i = 0
for i in range(len(xs)):
if xs[i] == key:
if i != len(xs):
return i
else:
return 'None'
for example,
xs = [3,4,5,6,4,4,5]
key = 4
the rightmost index output should be a single 5. But I got all three all them which are index 1,4,5.
Thanks for the help, and sorry I'm totally new.
what if the input as strings like:
xs=[True,True,True,False]
key = True
I believe the output is 2?
This simple solution should do:
def last_index(xs, key):
index = None
for i in xrange(len(xs)):
if xs[i] == key:
index = i # override index, result in the rightmost index of key
return index # returns None if key is not on the list
A more efficient way to do this is by iterating from the end to start and returning the index when key is found, in worst case - key is not found and we will iterate over the entire list.
Check out the more efficient version:
def last_index(xs, key):
index = None
for i in xrange(len(xs)-1, 0, -1): # iterate from last item to first
if xs[i] == key:
index = i
break # found the rightmost index, exit the loop
return index
Notice you should prefer using xrange over range (unless in python 3 where range equals to xrange), also to avoid an edge case when items involve different types see Andriy's answer.
You can try a function like this
def last_index(xs,key):
index = -1
for i in range(len(xs)):
if xs[i] == key:
index=i
if index!=-1:
return index
else:
return "none"
This will get the last index that matches your key. If there is none will return "none".
This should do the trick:
def last_index(xs,key):
index = -1
for i in range(len(xs)):
if xs[i] != key:
continue
else:
index = i
return index if index != -1 else 'None'
Traverse xs in reverse order and return first matched value, with reversed function:
def last_index(xs,key):
for i in reversed(range(len(xs))):
if xs[i] == key:
return i
xs = [3,4,5,6,4,4,5]
key = 4
print last_index(xs, key) # output: 5
xs=[True,True,True,False]
key = True
print last_index(xs, key) # output: 2
print last_index(xs, 2) # output: None
NOTE#1
You can use xrange instead of range it would give you better performace and won't be deprecated since python3, see Should you always favor xrange() over range()? for more info.
Your comparison may be improved by replacing
if xs[i] == key
to
if xs[i] == key and type(a) == type(b)
NOTE#2
To avoid bug when your 1 == True would return you index of True however you wanna index of 1 whicn not exist, compare result for both if conditions when xs and key have values below
xs=[True,True,True,False]
key = 1
See Strict comparison for more information about that behaviour.
You can reverse the list and then use .index():
index = xs[len(xs) - list(reversed(xs)).index(key)]
By the way, in your second list, True and False are booleans, not strings.
Iterate from behind like this:
def last_index(xs,key):
i= len(xs)-1
while i >=0:
if xs[i] == key:
return i
i -= 1
This way if the key does not exist the function will return the none value
Related
How to write python code that let the computer know if the list is a right sequence and the position doesn't matter, it will return true, otherwise it return false.
below are some of my example, I really don't know how to start
b=[1,2,3,4,5] #return true
b=[1,2,2,1,3] # return false
b=[2,3,1,5,4] #return true
b=[2,4,6,4,3] # return false
sort function is O(nlogn), we can use for loop which is O(n):
def check_seq(in_list):
now_ele = set()
min_ele = max_ele = in_list[0]
for i in in_list:
if i in now_ele:
return False
min_ele = min(i, min_ele)
max_ele = max(i, max_ele)
now_ele.add(i)
if max_ele-min_ele+1 == len(in_list):
return True
return False
Create a set and one to compare with -- based on minimum and maximum:
isRightSequence = set(range(min(b), max(b)+1)) == set(b)
This question is quite simple and can be solved a few ways.
The conditional approach - if there is a number that is bigger than the length of the list, it automatically cannot be a sequence because there can only be numbers from 1-n where n is the size of the list. Also, you have to check if there are any duplicates in the list as this cannot be possible either. If none of these conditions occur, it should return true
Using dictionary - go through the entire list and add it as a key to a dictionary. Afterwards, simply loop through numbers 1-n where n is the length of the list and check if they are keys in the dictionary, if one of them isn't, return false. If all of them are, return true.
Both of these are quite simply approaches and you should be able to implement them yourselves. However, this is one implementation for both.
1.
def solve(list1):
seen = {}
for i in list1:
if i > len(list1):
return False
if i in seen:
return False
seen[i] = True
return False
def solve(list1):
seen = {}
for i in list1:
seen[i] = True
for i in range (1, len(list1)+1):
if i not in seen:
return False
return True
This solution needs O(n) runtime and O(n) space
def is_consecutive(l: list[int]):
if not l:
return False
low = min(l)
high = max(l)
# Bounds Check
if high - low != len(l) - 1:
return False
# Test all indices exist
test_vec = [False] * len(l) # O(n)
for i in range(len(l)):
test_vec[l[i] - low] = True
return all(test_vec)
assert is_consecutive(range(10))
assert is_consecutive([-1, 1,0])
assert not is_consecutive([1,1])
assert not is_consecutive([1,2,4,6,5])
I need to code a function that takes as input a list of tuples, the number of tuples, and two numbers. This function should return True if the two given numbers exist in one of the tuples in our list.
For example : ma_fonction(l,n,i,j)
l: list of tuples
i and j two numbers between 0 and n-1 and i != j
I tried this code:
def ma_fonction(l,n,i,j):
checker = False
for item in l :
if ( i in item and j in item ):
cheker = True
return True
else:
return False
ma_fonction([(0,1), (5,2), (4,3)], 6, 2, 5)
But it doesn't work. What should I add or change?
I tried this ( somehow i didnt copy all my work in my question )
This is my work:
def ma_fonction(l,n,i,j):
checker = False
if((i!=j )and (0<=i<=n-1 )and( 0<=j<=n-1) ):
for item in l :
if ( i in item and j in item ):
cheker=True
return True
else:
return False
change your function to this:
def foo(l,n,i,j):
for item in l:
if (i in item and j in item):
return True
return False
You go over all tuples, and if i and j are in the tuple, you return True.
If it went over all tuples and didn't find a match, we can be sure that we can return False.
And this implementation really doesn't need the parameter n
The logic is that for each tuple in this list, check whether it contains the number i and j. If yes, then return True; if no, continue check the next tuple. Once you finish checking every tuple, and it turns out that there is no satisfied tuple, then return False.
def ma_fonction(l,n,i,j):
for item in l :
if ( i in item and j in item ):
return True
return False
This should work:
def ma_fonction(l,n,i,j):
for item in l :
if ( i in item and j in item ):
return True
return False
The reason your solution is not working is because you are returning False at the first element of the list that doesn't match with i and j. What you need to do is return False if and only if you looked in all the elements of the list and you couldn't find a match.
This question already has answers here:
How do I count the occurrences of a list item?
(29 answers)
Closed 5 years ago.
In short, I am making a function that takes 2 arguments 'sequence' and 'item'. The 'sequence' can be anything - an integer, a string, or a list containing integers or strings. I am trying to make a function that counts the amount of times 'item' occurs in the 'sequence'. Please take into account, I am still a newbie at Python. A simple answer would be very much appreciated.
This is what I have so far
def count(sequence, item):
found = 0
if sequence == item:
found += 1
return found
else:
for num in sequence:
if num == sequence:
found += 1
return found
else:
return False
print count([4,'foo',5,'hi'], 5)
The else part of the code is meant to be enabled if the sequence is something like a list. I was thinking I should loop through the list using for and do the same thing - but it's not working as it keeps returning False which follows the second 'else' statement. Any idea how I can do this? For clarification, the output in the example above should be 1 because '5' occurs once in the list.
len([i for i in sequence if item in i])
EDIT:
Changed return to return the number of occurrences instead of True/False
You are checking each item in sequence and evaluating, if it doesn't equal item it will return False right away, that is why you're getting False always.
You need to have your loop increment found and once the loop is done then use if/else to check whether found == 0 or not. A simple example:
def count(sequence, item):
found = 0
if sequence == item:
return 1
for num in sequence:
if num == item:
found += 1
return found
If you learned list-comprehension already, you can use it as the following:
def count(sequence, item):
if sequence == item:
return 1
return sum(1 for x in sequence if x == item)
If we use your code as a basis, we get the following if we want it to work.
You told it to loop over sequence, asking when num is equal to sequence, but one part of the list is not equal to the whole list. To fix this, we use an index. So we say, if item is equal to sequence[i], where is is an index, then we do found +=1. You also had the return statement in the for-loop, while you should get it outside of the for-loop, because it because breaks the loop. I hope this helps.
def count(sequence, item):
found = 0
if sequence == item:
found += 1
return found
else:
for num in range(len(sequence)):
if item == sequence[num]:
found += 1
if found > 0:
return found
else:
return False
You can use a recursive function to repeat calls on the count function when the first argument is a list, or use a simple == when it is not. This can equally handle nested lists by walking through the nesting recursively:
def count(sequence, item):
found = 0
if isinstance(sequence, list):
for x in sequence:
found += count(x, item)
else:
return int(item == sequence)
return found
print count([4,'foo',5,'hi', [5]], 5)
# 2
print count(5, 5)
# 1
I'd use collections.Sequence (or collections.abc.Sequence in Python 3) to determine if the items are sequences (lists, tuples, etc). If you just want to know if the item is in the list, which is what your code seems to be doing in spite of the name count:
from collections import Sequence
# In Python 3 it would be
# from collections.abc import Sequence
def count(sequence, item):
for i in sequence:
if item == i or (isinstance(i, Sequence) and item in i):
return True
return False
If you want to actually count the number of appearances of item in sequence:
from collections import Sequence
# In Python 3 it would be
# from collections.abc import Sequence
def count(sequence, item):
found = 0
for i in sequence:
if item == i or (isinstance(i, Sequence) and item in i):
found += 1
return found
There could be the possibility that a list within sequence contains in turn deeper sublists, and so on, in which case you may want a recursive algorithm. For finding if the element is contained you could go with:
from collections import Sequence
# In Python 3 it would be
# from collections.abc import Sequence
def count(sequence, item):
for i in sequence:
if item == i or (isinstance(i, Sequence) and count(i, item)):
return True
return False
For actually counting:
from collections import Sequence
# In Python 3 it would be
# from collections.abc import Sequence
def count(sequence, item):
found = 0
for i in sequence:
if item == i:
found += 1
elif isinstance(i, Sequence) and item in i:
found += count(i, item)
return found
PD: Note that strings are considered sequences, and therefore "b" in "abc" and "b" in ["a", "b", "c"] are both true. If you don't want "b" being considered an element of "abc" (i.e. you want to consider strings atomically, like numbers), you'd have to tune the code a bit. You could replace isinstance(i, Sequence) with isinstance(i, (list, tuple)), or with isinstance(i, Sequence) and not isinstance(i, basestring) (or, in Python 3, isinstance(i, Sequence) and not isinstance(i, (str, bytes))).
So I'm trying to figure out this problem and I can't figure out why it isn't working.
The premise is that you're given an input list and you have to find the second-lowest value. The list can have any number of integers and can repeat values; you can't change the list.
My code:
def second_min(x):
input_list = list(x)
print input_list
list_copy = list(input_list)
list_set = set(list_copy)
if len(list_set) > 1:
list_copy2 = list(list_set)
list_copy2 = list_copy2.sort()
return list_copy2[1]
else:
return None
print second_min([4,3,1,5,1])
print second_min([1,1,1])
The outputs for those two inputs are:
3
None
It's giving me errors on lines 9 and 13.
TypeError: 'NoneType' object has no attribute '__getitem__'
Thanks!
list_copy2 = list_copy2.sort()
.sort() sorts the list in place and returns None. So you're sorting the list, then throwing it away. You want just:
list_copy2.sort()
Or:
list_copy2 = sorted(list_set)
sorted always returns a list, so you can use it to sort the set and convert it to a list in one step!
You need to use sorted instead of sort. sorted returns a new list, that is a sorted version of the original. sort will sort the list in-place, and returns None upon doing so.
def second_min(x):
if len(x) > 1:
return sorted(x)[1]
else:
return None
>>> second_min([4,3,1,5,1])
1
Help, I can't use sorted! It's not allowed!
def second_min(li):
if len(li) < 2:
return None
it = iter(li)
a, b = next(it), next(it)
next_lowest, lowest = max(a, b), min(a, b)
for x in it:
if x < next_lowest:
if x < lowest:
lowest, next_lowest = x, lowest
else:
next_lowest = x
return next_lowest
I have written a function to check for the existence of a value in a list and return True if it exists. It works well for exact matches, but I need for it to return True if the value exists anywhere in the list entry (e.g. value <= listEntry, I think.) Here is the code I am using for the function:
def isValInLst(val,lst):
"""check to see if val is in lst. If it doesn't NOT exist (i.e. != 0),
return True. Otherwise return false."""
if lst.count(val) != 0:
return True
else:
print 'val is '+str(val)
return False
Without looping through the entire character string and/or using RegEx's (unless those are the most efficient), how should I go about this in a pythonic manner?
This is very similar to another SO question, but I need to check for the existence of the ENTIRE val string anywhere in the list. It would also be great to return the index / indices of matches, but I'm sure that's covered elsewhere on Stackoverflow.
If I understood your question then I guess you need any:
return any(val in x for x in lst)
Demo:
>>> lst = ['aaa','dfbbsd','sdfdee']
>>> val = 'bb'
>>> any(val in x for x in lst)
True
>>> val = "foo"
>>> any(val in x for x in lst)
False
>>> val = "fde"
>>> any(val in x for x in lst)
True
Mostly covered, but if you want to get the index of the matches I would suggest something like this:
indices = [index for index, content in enumerate(input) if substring in content]
if you want to add in the true/false you can still directly use the result from this list comprehension since it will return an empty list if your input doesn't contain the substring which will evaluate to False.
In the terms of your first function:
def isValInLst(val, lst):
return bool([index for index, content in enumerate(lst) if val in content])
where the bool() just converts the answer into a boolean value, but without the bool this will return a list of all places where the substring appears in the list.
There are multiple possibilities to do that. For example:
def valInList1 (val, lst):
# check `in` for each element in the list
return any(val in x for x in lst)
def valInList2 (val, lst):
# join the list to a single string using some character
# that definitely does not occur in val
return val in ';;;'.join(lst)