Given that l = [[1,2,3], [3,4,5],[5,6]], is there a method to return a list that consists of all positions of 3 within l; i.e. return [2,3]. A sample code I wrote is:
def pos_in_lists(seq, elem):
while i < len(seq):
elem_pos = seq[i].index(elem)
return [elem_pos]
When I run this, it only returns 2, which is not the result I want. What is my mistake? Also, is there a more simple way to solve my problem?
Your code only returns a list with one element (return [elem_pos]). You need to have a list variable (result) outside the loop to keep track of the result of previous lists by appending to that list.
def pos_in_lists(seq, elem):
result = []
i = 0
while i < len(seq):
if elem in seq[i]:
elem_pos = seq[i].index(elem)
result.append(elem_pos)
i += 1
return result
Another simpler alternative is to use list comprehension
def pos_in_lists(seq, elem):
return [l.index(elem) for l in seq if elem in l]
You need to increment "i" each loop
"return" forces the loop to exit. That should be outside the loop at the end of the code.
According to my understanding of the problem, Given list l = [[1,2,3], [3,4,5],[5,6]] and if we have to find 3, the output list should be [2,0].
Following mistakes are there in the code provided:
The code is not working as i is not defined in your method before using it.
We need to store positions of all 3 value present in the list, thus we need to have a list in which we store all the positions of 3 that we can find in the list. You have returned the result as soon as you have found one value. Thus, you are getting only 2.
seq[i].index(elem) will throw value error if 3 is not in the list.
Solution
def pos_in_lists(seq, elem):
res = []
for innerList in seq:
if elem in innerList:
res.append(innerList.index(elem))
return res
pos_in_lists(l,3)
Result would be [2,0]
we can use list comprehension as well:
def pos_in_lists(seq, elem):
return [innerList.index(elem) for innerList in seq if elem in innerList]
Related
def back_interleave(first, second):
if first == [] and second == []:
return []
elif first == []:
return second[::-1]
elif second == []:
return first[::-1]
else:
newlist = []
for i in range(len(first)-1, 0,-1):
newlist.append(first[i])
newlist.append(second[i])
for j in range(len(second)-len(first)-1,0,-1):
newlist.append(second[i])
return newlist
can anybody tells me what's wrong with my code towards this question.
I'm not exactly sure what's wrong with your code, but the second and third if-statements appear to use built-in list reversing functionality which the original problem forbids.
What I would do is determine the length of the longer list, then iterate through both lists backwards.
def back_interleave(first, second):
newlist = []
# You want to iterate through the length of the longer list
length = max(len(first), len(second))
for x in range(length):
# start appending elements from the back of the list
index = -1*(x+1)
if x < len(first):
newlist.append(first[index])
if x < len(second):
newlist.append(second[index])
return newlist
The problem in your code is when you use the range function, the stop value is exclusive i.e., the index 0 is becoming exclusive in your case. And also in the j loop the values at index i are being stored instead of the values at index j.
#CyanideTesla has given the code that works pretty well for your problem
This code snippet is one of posts in a LeetCode problem by fukuzawa_yumi
def splitArray(self, nums):
d,n={nums[0]:[0]},len(nums)
for i in range(1,n):
nums[i]+=nums[i-1]
if nums[i] not in d: d[nums[i]]=[i]
else: d[nums[i]].append(i)
for i in range(1,n-5):
for k in d.get(nums[-1]-nums[i-1],[]):
if i+3<k<n-1 and any(nums[i-1]+nums[j+1]==nums[k-1] for j in d.get(nums[i]+nums[i-1],[]) if i<j<k-2): return True
return False
The nums[0]:[0], d: d[nums[i]]=[i] are unfamiliar to me and I can't find explanation online.
Please, reference me in the right direction and give a few examples for posterity.
d,n={nums[0]:[0]},len(nums)
Is a somewhat ugly way of writing1:
d = {nums[0]: [0]}
n = len(nums)
It creates a dictionary d with a single item. The key is the first element in nums and the value is a one element list containing 0.
Later on, when you get to:
d[nums[i]] = [i]
This is a "replace-or-set" operation on the dictionary. The code is setting a dictionary item with key = nums[i] to a list with a single element whose value is i.
1In my subjective opinion :)
d,n={nums[0]:[0]},len(nums)
What this line is doing is:
bind d to a dictionary formed a single element with the key nums[0] (first element in list nums) and value [0] (a list containing 0)
bind n to the length of the list nums
It is possible to combine the two assignments on one line like this in Python. Python will perform the assignment of the variables based on the order. It's the same as doing tuple expansion.
I'm new to python. Could someone help me understand why the following function doesn't work? It is supposed to return a new list with the duplicates removed but instead prints [4,6].
def remove_duplicates(l):
solution = []
for item in l:
if l.count(item) < 2:
solution.append(item)
else:
l.remove(item)
return solution
print (remove_duplicates([4,5,5,5,4,6]))
I thought it iterates one item at a time in a list. So the first 5 would have a count of 3 and be remove, the second five would have a count of 2 and be removed and the third 5 would have a count of 1 and be appended to the solution list. I can't wrap my head around why the 5s would be completely removed but the 4s would not.
You must not remove items from a list, you are iterating at the moment. Iterating is done by incrementing an index internally.
If you want to keep the last occurence of an item, best, count them at first:
from collections import Counter
def remove_duplicates(l):
solution = []
counts = Counter(l)
for item in l:
if counts[item] == 1:
solution.append(item)
else:
counts[item] -= 1
return solution
Use set data type in python to remove the duplicates.
a = [4,5,5,5,4,6]
solution = list(set(a))
Output:
[4,5,6]
I've written a function to count unique elements in a 2d list in Python, and I'm wondering how to make it more general for lists of any number of dimensions. Answers I've seen so far about finding the dimension by testing if the first instance is a list don't seem robust. Please note I want to avoid using NumPy.
Any suggestions please?
def count_unique_elements_2d_list(list_2d):
flat_list = []
for sublist in list_2d:
for item in sublist:
flat_list.append(item)
unique_recipes = set(flat_list)
return len(unique_recipes)
This will return on the unique elements, which you can then call len on.
def get_unique(some_array, seen=None):
if seen is None:
seen = set()
for i in some_array:
if isinstance(i, list):
seen.union(get_unique(i, seen))
else:
seen.add(i)
return seen
What is happening?
This is a recursive problem. If the level is not a list, then assume it's an item and add it to the set of seen items. if it is a list, then run the function on it again.
You can avoid the extra space you have used by running two for loops and adding unique elements to the set only.
def count_unique_elements_2d_list(list_2d):
unique=set()
for sublist in list_2d:
for item in sublist:
unique.add(item)
return len(unique)
If the element is already present it would not be added to the set. And you will get the unique count of elements.
Here is my quick hack. It's a little unclean with the except but it's short and relatively efficient.
def get_dimensions(lut):
dim = 0
test = lut
try:
while test[0]:
dim = dim + 1
test = test[0]
except TypeError:
return dim
def to_onedimensional(lut, dim, output, counter):
if(counter == dim - 1):
for x in lut:
output.append(x)
else:
for x in lut:
to_onedimensional(x, dim, output, counter + 1)
This is how to use it:
lut = [[[3],[4]], [[2],[3]]]
print(get_dimensions(lut))
output = []
to_onedimensional(lut, get_dimensions(lut), output, 0)
res = set(output)
print(len(res))
Output:
3
3
Working in Python, how would I write code to remove negatives from an unknown list of integers using for loops and if statements?
def mod_lis (list):
for i in range(len(list)):
if list[i] < 0:
del list[i]
return list
The problem with your code is that you modify your list during your for loop. The result is that you jump over elements this way and get an IndexError soon since your list has been shortened.
You can do this with this list comprehension:
mylist = [val for val in mylist if val>=0]
You can use filter() and a lambda function:
my_list = filter(lambda x : x >= 0, mylist)
It's better to make a copy of the list without selected items, but if you have to modify in place, try this:
def remove_negatives(list):
pos = 0
for item in list:
if item >= 0:
list[pos] = item
pos += 1
del list[pos:]