Python - comparing value to an element of list of lists - python

Let's assume i got list like this:
list = [[1],[3],[4],[5],[8],[9],[12],[14],[15]]
then for some items in range(16) i want to compare these items to list elements and if they are equals do something.
For my best try i got a code like this:
for f in range(16):
if any(f == any(list) for x in list):
print('f: ',f)
in this case it prints only once for the f == 1, where I want it to get print() for each equal elements. I'm pretty sure I'm comparing int to list and I'm not getting desired result but in case like this I don't know how to get to inners list values : -/

You can use any here. You should also rename list to avoid shadowing the built-in type by that name.
l = [[1],[3],[4],[5],[8],[9],[12],[14],[15]]
for f in range(16):
if any(f in sub_list for sub_list in l):
print('f:', f)
any accepts an iterable, and returns True if any element of that iterable is true and False otherwise. What we are doing here is defining a generator comprehension (f in sub_list...) that checks each sublist for membership. Since any short-circuits (i.e. it doesn't keep checking elements once it has discovered one is True), using a lazily evaluating iterator saves unnecessary effort.
What was happening in your original code was that True also has a numeric value of 1 (mostly for legacy reasons). So since any(list) was always going to be True, f == any(list) is true only when f is 1

In this case you should try to have a list of integers. If it is not possible, I would use the following code:
l = [[1],[3],[4],[5],[8],[9],[12],[14],[15]]
for i in l:
if i[0] in range(16):
print(i[0])

Related

How to remove a value if its repeating more than once in a json?

I have a json like below
a = {"infinity_war":["Stark", "Hulk", "Rogers", "Thanos"],
"end_game":["Stark", "Dr.Strange", "Peter"]}
Since the name "Stark" is repeating more than once in the whole json I need to keep only one occurrence of "Stark" and remove the others. I tried using pandas but it needs all the list with same length. Is there any other way. The result I need is
a = {"infinity_war":["Stark", "Hulk", "Rogers", "Thanos"],
"end_game":["Dr.Strange", "Peter"]}
You can use a simple loop and a set to keep track of the seen elements:
seen = set()
b = {}
for k,l in a.items():
b[k] = [x for x in l if not (x in seen or seen.add(x))]
output:
{'infinity_war': ['Stark', 'Hulk', 'Rogers', 'Thanos'],
'end_game': ['Dr.Strange', 'Peter']}
How it works:
for each key/list pair, iterate over the elements of the list. If an element is found in the seen set, skip adding it to the new list, else append it to the seen set and add it to the new list.
seen.add(x) is always False as set.add returns None, so (x in seen or seen.add(x)) has the boolean value of x in seen, which we invert with not.

Python function that takes a list and returns a new list with unique elements of the first list

I'm trying to solve this problem by using this code
def unique_list(numbers):
unique = []
for item in numbers :
if item in unique == False:
unique.append(item)
return unique
But every time i'm calling this function, I get an empty list
Can somebody help thus beginner ? I don't understand where i'm going wrong
As Oksana mentioned, use list(set(numbers)).
As for you code, change if item in unique == False to if item not in unique. But note that this code is slower, since it has to scan the list for every new element that it tries to add:
def unique_list(numbers):
unique = []
for item in numbers :
if item not in unique:
unique.append(item)
return unique
print(unique_list([1, 2, 3, 1, 2]))
# [1, 2, 3]
As SET only contain unique value, we can use it to get your answer.
Use this python function code
def unique_list(numbers):
x=set(numbers) #unique numbers in set
y=list(x) #convert set to list as you want your output in LIST.
print(y)
EXAMPLE:
unique_list([2,2,3,3,3])
OUTPUT Will be a unique list.
[2,3]
Edit:
Actually, as pointed out by DeepSpace below, this is wrong! Curiously, It isn't evaluated as (item in unique) == False nor as item in (unique == False).
It's caused by operator precedence. In the line:
item in unique == False:
Python first resolves the unique == False expression, which checks if the variable unique is equals to False (which isn't true, it is a list).
So, that line becomes
if item in False:
So, the if block is never executed! To fix it, you can wrap item in unique in parenthesis, such as:
if (item in unique) == False:
BUT, there's a very useful data structure in Python that serves your purpose: Set. A Set holds only unique values, and you can create it from a existing list! So, your function can be rewritten as:
def unique_list(numbers):
return list(set(numbers)) # It converts your original list into a set (with only unique values) and converts back into a list
We cannot check if the item in unique is false or true like that, instead we use 'not'. Try this:
if not item in unique:
unique.append(item)
def unique_list(lst):
a = set(lst)
return list(a)

How to use append in for loop for multiple value list when only a single value is returning?

I am trying to create a function that when passed a list of names of any length, will return a list of only those names that are exactly four characters in length. I want the output list to be comma delimited.
I have attached code of what I have tried. I tried to get the function to iterate through the list parameter passed to the function 'x' and then if the length of that list value is four characters long, add it to the output list.
I expected the output list to be ['Ryan','Mary'] but it's just ['Ryan'] as is.
I'm new to all this and don't understand why what I've done isn't working.
output = []
def friend(x):
for i in range(len(x)):
if len(x[i]) == 4:
return output.append(x[i])
list = ["Ryan","Kieran","Jason","Mary"]
friend(list)
print(output)
You don't want to return so early. you are not giving your function enough passes through your list to get more than 1 element with 4 letters. You want to take time to build your list before returning it. I would build up the output list then, once we are done looping entirely, return it:
def friend(x):
output = []
for i in range(len(x)):
if len(x[i]) == 4:
output.append(x[i])
return output
list = ["Ryan","Kieran","Jason","Mary"]
myOutput = friend(list)
print(myOutput)```
There are actually numerous ways to tackle this issue
One way is list comprehension:
list = ["Ryan","Kieran","Jason","Mary"]
print([name for name in list if len(name) == 4]) # iterate list using variable name, check if len(name) == 4, and add it to the list if it's true
Another way is making use of yield:
def friend(x):
for i in range(len(x)):
if len(x[i]) == 4:
yield x[i] # note that this returns a generator, not a list. Basically, you can only iterate once
Another way, using list comprehension, you can shorten your function like :
def friend(x):
return [k for k in x if len(k)==4]
list_ = ["Ryan","Kieran","Jason","Mary"]
print(friend(list_))
OUTPUT :
['Ryan', 'Mary']
Firstly I want to add that you should not use list (and other types names) as variable name. Also alternatively to list comprehension you might use filter function, example usage:
lst = ["Ryan","Kieran","Jason","Mary"]
output = list(filter(lambda x:len(x)==4,lst))
print(output) #['Ryan', 'Mary']
Note that filter requires function which takes element of lst as argument and returns False (jettison) or True (retain). I want to note that personally I find list comprehension more readable in this case and I just wanted to show function filter which could be encountered in situation requiring choice of certain elements from list.
You can use a list comprehension
output = [name for name in list_of_names if len(name)==4]
print(output)

Sort a list with certain values staying in constant positions

I have a list of strings. I want to only sort values that meet a certain condition. Consider this list
['foo','bar','testa','python','java','abc']
and I only want to sort the values with an a in them. The result should look like this
['foo','abc','bar','python','java','testa']
The elements with a will change places appropriately, but the other elements retain their original positions.
I have absolutely no idea how to implement this, so I hope someone else does. Can someone show me how to do this?
y = sorted(w for w in x if 'a' in w) # pick and sort only the elements with 'a'
x = [w if 'a' not in w else y.pop(0) for w in x]
The last line leaves word without an 'a' in them unchanged, while those with 'a' are picked progressively from the y list (that is already sorted)
EDIT:
#MartijnPieters solution performs better, since it uses an iterator and won't use additional memory to store y.
y = iter(sorted(w for w in x if 'a' in w)) # create iterator, don't use memory
x = [w if 'a' not in w else next(y) for w in x] # yield from iter instead of popping from a list
Since it looks like you need this algorithm to work with different condition, you could put this into a method:
x = ['foo','bar','testa','python','java','abc']
def conditional_sort(ls, f):
y = iter(sorted(w for w in ls if f(w)))
return [w if not f(w) else next(y) for w in ls]
conditional_sort(x, lambda w: 'a' in w)
The first parameter would be the list, the second one a function that takes a single parameter and returns a bool value.
Find the elements with a; mark the positions and pull them out.
orig = ['foo','bar','testa','python','java','abc']
just_a = [str for str in orig if `a` in str]
mark = [`a` in str for str in orig]
This gives us
just_a = ['bar', 'testa', 'java', 'abc']
mark = [False, True, True, False, True, True]
Sort just_a; I'm sure you can do that. Now, build your result: where there's True in mark, take the next item in the sorted list; otherwise, take the original element.
result = []
for pos in range len(orig):
if mark[pos]:
result.append(sort_a.pop())
else:
result.append(orig[pos])
This can be done with much less code. Among other things, this last loop can be done with a list comprehension. This code merely clarifies the process.
A possible approach would be to :
Extract all values with an 'a' in them and note their positions.
Sort the values alphabetically (see this post).
Insert the sorted values into the original list.
This can definitely be simplified, but here's one way of doing it
def custom_sort(lst):
sorted_list = [x for x in lst if 'a' in x] # get list of everything with an a in it
sorted_list.sort() # sort this of elements containing a
final_list = [] # make empty list, we will fill this with what we need
sorted_counter = 0 # need a counter to keep track of what element containing a have been accounted for below
for x in lst: # loop over original list
if 'a' in x: # if that element in our original list contains an a
final_list.append(sorted_list[sorted_counter]) # then we will from our sorted list of elements with a
sorted_counter += 1 # increment counter
else: # otherwise
final_list.append(x) # we add an element from our original list
return final_list # return the custom sorted list
I just would use two additional lists to keep track of the indices of words with 'a' and to sorted the words:
L=['foo','bar','testa','python','java','abc']
M=[]
count=[]
for t in L:
if 'a' in t:
M.append(t) #append both the word and the index
count.append(L.index(t))
M=sorted(M)
for l in count:
L[l]=M[count.index(l)]
L
Probably is not very efficient but it works.

Check whether a list starts with the elements of another list

What is the easiest (most pythonic way) to check, if the beginning of the list are exactly the elements of another list? Consider the following examples:
li = [1,4,5,3,2,8]
#Should return true
startsWithSublist(li, [1,4,5])
#Should return false
startsWithSublist(list2, [1,4,3])
#Should also return false, although it is contained in the list
startsWithSublist(list2, [4,5,3])
Sure I could iterate over the lists, but I guess there is an easier way. Both list will never contain the same elements twice, and the second list will always be shorter or equal long to the first list. Length of the list to match is variable.
How to do this in Python?
Use list slicing:
>>> li = [1,4,5,3,2,8]
>>> sublist = [1,4,5]
>>> li[:len(sublist)] == sublist
True
You can do it using all without slicing and creating another list:
def startsWithSublist(l,sub):
return len(sub) <= l and all(l[i] == ele for i,ele in enumerate(sub))
It will short circuit if you find non-matching elements or return True if all elements are the same, you can also use itertools.izip :
from itertools import izip
def startsWithSublist(l,sub):
return len(sub) <= l and all(a==b for a,b in izip(l,sub))

Categories