Python Produce empty list if condition not satisafied - python

I am creating a if condition-based list. I want to create an empty list if the condition is not satisfied.
My code:
ip_list = []
op_list= [ip_list[0] if len(ip_list)>0 else '']
Present output:
op_list = ['']
Expected output:
op_list = []

This can be accomplished more succinctly via slicing:
op_list = ip_list[:1]
If ip_list has at least one element, op_list will be a singleton list with the first element of ip_list. Otherwise, op_list will be an empty list.
>>> a = [1, 2, 3]
>>> b = []
>>> a[:1]
[1]
>>> b[:1]
[]

op_list = [] if ip_list else [ip_list[0]]

You only need the first element if ip_list has any.
Here is one of the easiest solution for that:
[ip_list[0]] if ip_list else []

Related

How to create lists using for loop in Python

What I want to get is
[a][b][c]
Getting each index from an array a=[a,b,c]. I’m using this to approach a value in dictionary.
All I could find was .append() but this returns me [a,b,c] not [a][b][c]
This is the function that I made
Def loop():
Newlist = []
for i in a:
Newlist.append(i)
return Newlist
You want to append a list of one value, not a single value. i.e.
>>> new_list = []
>>> new_list.append([1])
>>> new_list.append([2])
>>> new_list.append([3])
[[1], [2], [3]]
So in the method you'd do something like this:
def loop():
new_list = []
for i in a:
new_list.append([i])
return new_list
Try this:
Create a new list inside the loop that gets reset each time, add your variable, then add the new list to the parent list.
You can also grab individual lists from the parent list using the following: Newlist[1]
Def loop():
Newlist = []
for i in a:
temp_list = []
temp_list.append(I)
Newlist.append(temp_list)
return Newlist

Selecting 1st element of every list within list

I have the following list of lists with multiple elements:
list = [[1633425661439, 0.11643042583898743],
[1633428739018, 0.11682454707026001],
[1633432086311, 0.11950356856187618]]
I want to populate a new_list1 and new_list2 with the first and second numbers within each of those lists, respectively, yielding:
new_list1 = [1633425661439,
1633428739018,
1633432086311]
And:
new_list2 = [0.11643042583898743,
0.11682454707026001,
0.11950356856187618]
I tried:
for n in list:
for i in n:
new_list1.append(i[0])
new_list2.append(i[1])
But got: TypeError: 'int' object is not subscriptable
You can try something
list_ = [[1633425661439, 0.11643042583898743],
[1633428739018, 0.11682454707026001],
[1633432086311, 0.11950356856187618]]
list_a = [first[0] for first in list_]
list_b = [first[1] for first in list_]
Other way
new_list1 = []
new_list2 = []
for inner_list in list_:
new_list1.append(inner_list[0])
new_list2.append(inner_list[1])
You can transpose it like this:
lst = [[1633425661439, 0.11643042583898743],
[1633428739018, 0.11682454707026001],
[1633432086311, 0.11950356856187618]]
new_list_1, new_list_2 = map(list, zip(*lst))
And if you are ok with tuples instead of lists, the following will do:
new_list_1, new_list_2 = zip(*lst)
And you really should not name a variable list. It shadows the built-in type.
You can also use simple comprehensions:
new_list_1 = [a for a, _ in lst]
new_list_2 = [a for _, a in lst]
Some docs:
map
zip
You have one level of nesting too much, this would
for n in list:
for i in n:
print(i)
would print single elements, which are numbers, you need to do
for n in list:
new_list1.append(n[0])
new_list2.append(n[1])
As side note, please avoid using list as it is already used name in python. Overshadowing it might cause unexpected behavior, you can use lst name i.e.:
lst = [[1,2],[3,4],[5,6]]
new_lst1 = []
new_lst2 = []
for n in lst:
new_lst1.append(n[0])
new_lst2.append(n[1])
print(new_lst1)
print(new_lst2)
output
[1, 3, 5]
[2, 4, 6]
you can unpack the first and second number in the for loop itself.
(BTW best not call the variable "list" because it is the same as a python build-in)
list_ = [[1633425661439, 0.11643042583898743],
[1633428739018, 0.11682454707026001],
[1633432086311, 0.11950356856187618]]
new_list1 = []
new_list2 = []
for (i, j) in l:
new_list1.append(i)
new_list2.append(j)
Following PEP-8 code style guideline please do not name the variables with reserved keywords like list, dict, for, etc.
With the second loop you iterate over int numbers within the inner lists.
If you need to use only the first 2 elements of each list, one loop os enough:
list_ = [
[1633425661439, 0.11643042583898743],
[1633428739018, 0.11682454707026001],
[1633432086311, 0.11950356856187618]]
for inner_list in list_:
new_list1.append(inner_list[0])
new_list2.append(inner_list[1])
list= [[1633425661439, 0.11643042583898743], [1633428739018, 0.11682454707026001], [1633432086311, 0.11950356856187618]]
new_list1 = [ ]
new_list2 = [ ]
for inner_list in list:
new_list1.append(inner_list[0])
new_list2.append(inner_list[1])
print(new_list1)
print(new_list2)

Shedding list layers - Python

How could you turn:
[[["hi"], ["hello"]]]
into:
[["hi"], ["hello"]]
While also working with [] as an input
You can use pop function to take the first item out of the list.
>>> a = [["hi"]]
>>> a = a.pop(0)
>>> a
['hi']
Or you can also do something like:
>>> a = [["hi"]]
>>> a = a[0]
>>> a
['hi']
As you edited your question:
>>> a = [[["hi"], ["hello"]]]
>>> a = a.pop(0)
>>> a
[['hi'], ['hello']]
If you have an empty list:
a = []
try:a = a.pop(0) #try if it don't raises an error
except:pass #if error is raised, ingnore it
So , according to the code above, if the list is empty , it will not raise any error.
If you want it to be more simpler:
a = []
if len(a) != 0:a = a[0]
print(a)
You can also make a function to make it simple to use with empty or non-empty lists:
def get(list):
return list if len(list) == 0 else list[0]
Testing our function:
>>> get([])
[]
>>> get([["Hi","Bye"]])
['Hi', 'Bye']
You can use a nested list comprehension to flatten it:
list_of_lists = [['hi'],['hello']]
flattened = [val for sublist in list_of_lists for val in sublist]
print(flattened)
This also works if you have multipe sublists in your list.
You can read more about this on python's documentation
Use itertools
import itertools
ip = [["hi"]]
op = list(itertools.chain.from_iterable(ip))
# op ["hi"]
Or a numpy solution using ravel
import numpy as np
ip = [["hi"]]
ip = np.array(ip)
op = list(ip.ravel())
Since you edited your question, you only want n-1 dimensions, you could use np.transpose -
ip = [[["hi"], ["hello"]]]
op = ip.transpose().reshape(2, 1)
You could check if your input is empty[] explicitly before doing any operations on it, that way to avoid errors -
if ip:
# do some operations on ip

Finding indices of items from a list in another list even if they repeat

This answer works very well for finding indices of items from a list in another list, but the problem with it is, it only gives them once. However, I would like my list of indices to have the same length as the searched for list.
Here is an example:
thelist = ['A','B','C','D','E'] # the list whose indices I want
Mylist = ['B','C','B','E'] # my list of values that I am searching in the other list
ilist = [i for i, x in enumerate(thelist) if any(thing in x for thing in Mylist)]
With this solution, ilist = [1,2,4] but what I want is ilist = [1,2,1,4] so that len(ilist) = len(Mylist). It leaves out the index that has already been found, but if my items repeat in the list, it will not give me the duplicates.
thelist = ['A','B','C','D','E']
Mylist = ['B','C','B','E']
ilist = [thelist.index(x) for x in Mylist]
print(ilist) # [1, 2, 1, 4]
Basically, "for each element of Mylist, get its position in thelist."
This assumes that every element in Mylist exists in thelist. If the element occurs in thelist more than once, it takes the first location.
UPDATE
For substrings:
thelist = ['A','boB','C','D','E']
Mylist = ['B','C','B','E']
ilist = [next(i for i, y in enumerate(thelist) if x in y) for x in Mylist]
print(ilist) # [1, 2, 1, 4]
UPDATE 2
Here's a version that does substrings in the other direction using the example in the comments below:
thelist = ['A','B','C','D','E']
Mylist = ['Boo','Cup','Bee','Eerr','Cool','Aah']
ilist = [next(i for i, y in enumerate(thelist) if y in x) for x in Mylist]
print(ilist) # [1, 2, 1, 4, 2, 0]
Below code would work
ilist = [ theList.index(i) for i in MyList ]
Make a reverse lookup from strings to indices:
string_indices = {c: i for i, c in enumerate(thelist)}
ilist = [string_indices[c] for c in Mylist]
This avoids the quadratic behaviour of repeated .index() lookups.
If you data can be implicitly converted to ndarray, as your example implies, you could use numpy_indexed (disclaimer: I am its author), to perform this kind of operation in an efficient (fully vectorized and NlogN) manner.
import numpy_indexed as npi
ilist = npi.indices(thelist, Mylist)
npi.indices is essentially the array-generalization of list.index. Also, it has a kwarg to give you control over how to deal with missing values and such.

Set list to None in list comprehension

In the following code any element after splitting does end with 'div' then it should be the resultant of new list but right now i get b = [''] .My question is how to make the list empty b=[]
a=['1div,2div,3div,4div,5div']
b= [','.join(i for i in a[0].split(',') if not a.endswith('div'))]
After fixing the errors in your code, you can do:
result = [','.join(i for i in a[0].split(',') if not i.endswith('div'))]
b = result if result[0] else []
#or
result = ','.join(i for i in a[0].split(',') if not i.endswith('div'))
b = [result] if result else []
And using just a one element list makes no sense here.
what about:
filter(lambda x: not x.endswith('div'), a[0].split(","))

Categories