I am trying to make a function that is able to find a element in a nested list.
That is what if got so far:
def in_list(ele, lst, place):
if ele == lst[place]:
return True
else:
for i in range(len(lst)):
in_list(ele, lst[i], place)
This is what i input:
a=[[1,2],[3,4]]
if in_list(2,a,1)==True:
print("True")
the variable "place" is the place in the list where the element should be found...
Now somehow it doesn't understand this line if ele == lst[place]
this is the error message: TypeError: 'int' object is not subscriptable
Thanks in advance
There are two issues in the last line
def in_list(ele, lst, place):
if ele == lst[place]:
return True
else:
for i in range(len(lst)):
in_list(ele, lst[i], place)
lst[i] is an integer (assuming lst is a list of integers), which is why you get your error.
The other issue is that you're not returning anything from the else branch.
Something like this might work better in case of arbitrary, but uniform, nesting:
def recursive_contains(item, lst):
if len(lst) == 0:
return False
elif isinstance(lst[0], collections.Iterable):
return any(recursive_contains(item, sublist) for sublist in lst)
else:
return item in lst
for arbitrary non-uniform nesting, perhaps something like this:
def recursive_contains(item, lst):
if not isinstance(lst, collections.Iterable):
return item == lst
for val in lst:
if item == val:
return True
elif isinstance(val, collections.Iterable):
if recursive_contains(item, val):
return True
return False
of course if you only have 2 levels (all elements of lst are lists of int), you could simply say:
if ele in sum(lst, []):
...
which uses sum to flatten the list first.
The other answers well define the mistake in your code.
Just to reiterate that you were assuming each element in the list as a nested list and subscripting it like - elem[place].
You can't subscript a primitive type such as integer and hence the error.
Refer the below code to handle nesting.
Note - You Don't require the 3rd parameter of place, more appropriately you wouldn't the place if you are searching.*
def fetch(data, l):
for element in l:
if type(element) == list:
if fetch(data, element):
return True
else:
if element == data:
return True
return False
On further thought you are looking for an element that should be only at "place" index of any of the nested lists.
Refer to the snippet below for that-
def fetch(data, l,place):
if data == l[place]:
return True
else:
for element in l:
if type(element) == list and fetch(data,element,place):
return True
return False
Note- Only call fetch again if the element is a list.
a = [[1, 2], [3, 4]]
def inlist(e, l, p):
for lists in range(len(l)):
print("array:", l[lists])
print("Looking for", e)
print("In position", p)
print(l[lists][p])
if l[lists][p] == e:
print(True, ": The element ", e, " is in the list n.", lists, " at the place ", p)
return True
inlist(2, a, 1)
Output
array: [1, 2]
Looking for 2
In position 1
2
True : The element 2 is in the list n. 0 at the place 1
Related
My code:
def shorter(lst):
if len(lst) == 0:
return []
if lst[0] in lst[1:]:
lst.remove(lst[0])
shorter(lst[1:])
return lst
print shorter(["c","g",1,"t",1])
Why does it print ["c","g",1,"t",1] instead of ["c","g","t",1]
For a recursive method, what you can do is check a specific index in the again as you have it. If we remove the current element, we want to stay at the same index, otherwise we want to increase the index by one. The base case for this is if we are looking at or beyond the last element in the array since we don't really need to check it.
def shorter(lst, ind=0):
if ind >= len(lst)-1: #Base Case
return lst
if lst[ind] in lst[ind+1:]:
lst.pop(ind)
return shorter(lst,ind)
return shorter(lst, ind+1)
#Stuff to test the function
import random
x = [random.randint(1,10) for i in range(20)]
print(x)
x = shorter(x)
print(x)
Another way to solve this in a single line is to convert the list into a set and then back into a list. Sets have only unique values, so we can use that property to remove any repeating elements.
import random
x = [random.randint(1,10) for i in range(20)]
print(x)
x = list(set(x)) #Converts to set and back to list
print(x)
A possible recursive solution could be:
def shorter(lst):
if lst:
if lst[0] in lst[1:]:
prefix = [] # Skip repeated item.
else:
prefix = [lst[0]] # Keep unique item.
return prefix + shorter(lst[1:])
else:
return lst
The previous code can also be compacted to:
def shorter(lst):
if lst:
return lst[0:(lst[0] not in lst[1:])] + shorter(lst[1:])
else:
return lst
and the function body can also be reduced to a one-liner:
def shorter(lst):
return (lst[0:(lst[0] not in lst[1:])] + shorter(lst[1:])) if lst else lst
or even:
def shorter(lst):
return lst and (lst[0:(lst[0] not in lst[1:])] + shorter(lst[1:]))
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.
we need to be able to make a function that has 1 list as an input. We need to split the even numbers from the uneven numbers and put them in seperate lists. We are not permitted to make a second list and should be able to solve it only using recursion, and with car, cdr, cons, ... .
This is what I already have:
def split_list(list_a):
if null(list_a):
return []
elif not even(car(list_a)):
return cons(car(list_a), split_list(cdr(list_a)))
else:
return cons(splits_lijst(cdr(list_a)), car(list_a))
print(split_list([1, 2, 3, 4]))
I became the output: [1, 3, 4, 2]
While it should be: [1, 3][2, 4]
I really have no clue how to do this without making a secondary list.
Just to be clear, the functions in the function 'split_list' are car, cdr, cons, null and even. Here you see the contents of those functions:
def car(a_list):
return a_list[0]
def cdr(a_list):
return a_list[1:]
def null(a_list):
return True if len(a_list) == 0 else False
def cons(a, b):
new_list = []
if type(a) is list:
for item in a:
new_list.append(item)
else:
new_list.append(a)
if type(b) is list:
for item in b:
new_list.append(item)
else:
new_list.append(b)
return new_list
def even(x):
if x == 1:
return False
elif x == 0:
return True
else:
return even(x-2)
You need a way to make two lists during your iteration of one list. The best way to do that is to make a function that takes 3 arguments. one for the input and 2 for the two output lists, often called accumulators.
The logic would be to return a list of the two accumulators when you have reached the end of the list. If not you check the element for evenness and recurse by adding it to the even accumulator. If not you recurse by adding the element to the odd accumulator.
I think this would help you.
l=list(range(10))
evens=[]
odds=[]
for x in l:
if x%2==0:
evens.append(x)
else:
odds.append(x)
print(evens,odds)
the below one will use only one additional list,(in case you don't require the original one):
l=list(range(10))
odds=[]
for x in l:
if x%2==0:
continue
else:
l.remove(x)
odds.append(x)
print(l,odds)
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))).
Question is:
Define a recursive function named separate; it is passed a predicate and a list; it returns a 2-tuple whose 0 index is a list of all the values in the argument list for which the predicate returns True, and whose 1 index is a list of all the values in the argument list for which the predicate returns False. The call separate(predicate.is_positive,[1,-3,-2,4,0,-1,8]) returns ([1,4,8], [-3,-2,0,-1]). Note 0 is not positive. Hint: like the fast version of the power function in the notes, you can define and bind (but not rebind) a local name or can write a nested function (like square in power) to help with the computation.
Here is the example of his power function:
def power(a,n):
def square(n) : n*n
if n == 0:
return 1
else:
if n%2 == 1:
return a*power(a,n-1)
else:
return square( power(a,n//2) )
My attempt:
def separate(p,l):
l1=[]
l2=[]
if l == []:
return [],[]
else:
if p(l[0]):
l1=([l[0]]+map_pos(p,l[1:]))
return l1,l2
else:
l2.extend([l[0]]+separate(p,l[1:]))
return l1,l2
calling this function:
print(predicate.is_positive,[1, -3, -2, 4, 0, -1, 8]) will gives me:
TypeError: can only concatenate list (not "tuple") to list
Note predicate.is_positive is a function from predicate module which takes an int and return True if int is positive.
Can someone please help me with this? With actual code will be nice really appreciated.
This may be whay you are attempting to do
def separate(p, L):
if L == []:
return [], []
l1, l2 = separate(p, L[1:])
item = L[0]
if p(item):
l1.append(item)
else:
l2.append(item)
return l1, l2
It's not very efficient due to the L[1:] which creates a new list for each item
you can use a default argument to avoid making the slices
def separate(p, L, idx=0):
if idx == len(L):
return [], []
l1, l2 = separate(p, L, idx + 1)
item = L[idx]
if p(item):
l1.append(item)
else:
l2.append(item)
return l1, l2
It still looks clumsy. It's not really a task that calls for a recursive solution