Removing empty strings in a list - python-3.x

I have a list in the form
lst = ['', 'how', '', 'are', 'you', '']
and want to convert it into
lst = ['how','are', 'you']
I have currently used the code list(filter(None,lst)) but no changes are returned. How can i remove the empty strings?

Your code must works but an other solution is using lambdas:
lst = list(filter(lambda x: x != '', lst))
print(lst)
Output: ['how', 'are', 'you']

A simple and possible solution is the following:
lst = ['', 'how', '', 'are', 'you', '']
lst = [element for element in lst if element != '']
Now, lst is ['how', 'are', 'you']

Here you forgot to make the filter to this kinda thing:
lst = ['', 'how', '', 'are', 'you', '']
lst = list(filter(None, lst))
print(lst)
you define the list as list(filter(None, lst))

Are you printing lst again? Your code works for me.
lst = ['', 'how', '', 'are', 'you', '']
lst = list(filter(None,lst))
print(lst)
outputs ['how', 'are', 'you']

Related

Need to generate a dictionary using comprehension

I have this code in python:
layers = ['two', 'three', 'five', 'six']
dict_toggle_bullet = {}
for x, y in enumerate(layers):
dict_toggle_bullet[y] = ["active" if j == y else "" for _, j in enumerate(layers)]
The output is:
{'two': ['active', '', '', ''], 'three': ['', 'active', '', ''], 'five': ['', '', 'active', ''], 'six': ['', '', '', 'active']}
Is there a way to convert this using dictionary comprehension in a single line?
This is what I came up with:
lst = ['two','three','five','six']
d = {lst[i]:['' if j != i else 'active' for j in range(4)] for i in range(4)}
However, I wouldn't advice you to do this as it seems a bit complicated and difficult to understand, so the direct method looks to be better.

Collect and put special key and value together in a dictionary

I would like to get a very uncommon output, as the follows Desired output shows:
I have tried many ways for a whole day, but still, no idea how to get it.
Two lists:
a = ['11', '22', '33','44', '55', '66']
b = ['E', 'AA', 'AA','AA', 'SS', 'SS']
Desired output:
{'11': ['E'],
'22': ['AA','33','44'], # order does not matter
'33': ['AA','22','44'],
'44': ['AA','22','33'],
'55': ['SS','66'],
'66': ['SS','55']}
For better ubderstanding, if a and b are:
a = ['11', '22', '33','44', '55', '66']
b = ['E', 'AA', 'AA','AA', 'SS', 'AA']
Desired output:
{'11': ['E'],
'22': ['AA','33','44','66'], # order does not matter
'33': ['AA','22','44','66'],
'44': ['AA','22','33','66'],
'55': ['SS'],
'66': ['AA','22','33','44']
}
Question:
Which is suitable to get my desired output? tuple, dictionary or set?
My current status:
a = ['11', '22', '33','44', '55', '66']
b = ['E', 'AA', 'AA','AA', 'SS', 'SS']
#put them into a dictionary:
dict_1 = {}
for i, j in zip(a, b):
dict_1.setdefault(i, []).append(j)
print(dict_1)
c = list(zip(a,b))
i=0
#find the target tuples
while i<len(c):
j = i+1
while i < j < len(c):
if c[i][1] == c[j][1]:
print('Got a repeat one')
print(c[i], c[j])
j+=1
i+=1
Current output:
{'11': ['E'], '22': ['AA'], '33': ['AA'], '44': ['AA'], '55': ['SS'], '66': ['SS']}
Got a repeat one
('22', 'AA') ('33', 'AA')
Got a repeat one
('22', 'AA') ('44', 'AA')
Got a repeat one
('33', 'AA') ('44', 'AA')
Got a repeat one
('55', 'SS') ('66', 'SS')
Open question:
once got the target tuples, how can I combine them to get my desired output, I have tried using .append, but it is a mass.
Incorrect output while trying to collect targets:
['AA', '33', 'AA', '44', 'AA', '44', 'SS', '66']
['AA', '33', '44', 'SS', '66']
If anyone has a hint on this, I much appreciate it, thanks in advance!
Try:
a = ["11", "22", "33", "44", "55", "66"]
b = ["E", "AA", "AA", "AA", "SS", "AA"]
tmp = {}
for i, j in zip(a, b):
tmp.setdefault(j, []).append(i)
out = {}
for k, v in tmp.items():
for i in v:
vc = v.copy()
vc.remove(i)
vc.append(k)
out[i] = vc
print(out)
Prints:
{'11': ['E'],
'22': ['33', '44', '66', 'AA'],
'33': ['22', '44', '66', 'AA'],
'44': ['22', '33', '66', 'AA'],
'66': ['22', '33', '44', 'AA'],
'55': ['SS']}
Here's a possible solution,
# Assumes the lists are equal length
# Input 1
#a = ['11', '22', '33','44', '55', '66']
#b = ['E', 'AA', 'AA','AA', 'SS', 'SS']
# Input 2
a = ['11', '22', '33','44', '55', '66']
b = ['E', 'AA', 'AA','AA', 'SS', 'AA']
# Dictionary with instances of a that
# correspond to b - assumes all elements
# of a are unique
a_in_b = {}
for el_a, el_b in zip(a,b):
if el_b in a_in_b:
# If already a key there, append
a_in_b[el_b].add(el_a)
else:
# Initialize a new list
a_in_b[el_b] = set([el_a])
# Check it
#print(a_in_b)
# Now get the final structure
output = {}
for el_a, el_b in zip(a,b):
output[el_a] = [el_b]
rest = a_in_b[el_b] - set([el_a])
if rest:
# If not empty
output[el_a] += list(rest)
print(output)
It first creates a dictionary of all elements in a that would correspond to elements in b, then it constructs the desired output. It uses sets, because of the set difference used later, the - operator.
Note the assumptions as highlighted in the code: a and b are the same size, and a entries are unique. If they are not, then you'd need to use a list. Depending on your requirements you would have to change the - approach too.
Also, consider adjusting the names of variables into something that reflects your application better.

How to join segments of a list

I have found different answers elsewhere that will work, but I can't quite figure out why my code is not working properly. What I am trying to do is take a list of alphabetical characters and join the first 4, second 4, third 4, etc. elements. I'll paste an example below to make this more clear.
If given the following list:
['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'I', 'M', 'N', 'O', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']
I want to combine the elements so that I receive the following output:
['ABCD', 'EFGH', 'IJKL', 'IMNO', 'QRST', 'UVWX', 'YZ']
I thought I identified a good solution on my own, but it doesn't seem to work. What I tried was:
x = 'ABCDEFGHIJKLIMNOQRSTUVWXYZ'
y = 4
def wrap(string, max_width):
slist = [char for char in string]
new = []
for i in range(0, len(slist), max_width):
new.append(''.join(slist[i:max_width]))
return new
wrap(x, y)
The output that I get from this is:
['ABCD', '', '', '', '', '', '']
I would appreciate if if someone could help me identify what is wrong and help me fix it. Like I said previously, I have found other answers online that will do what I want, but I really want to figure out where I went wrong here.
It looks like there was logic issues in the for loop:
You were trying to add items between i:max_width. However max_width is always 4 and when i is > 4 you get no items return as it is an empty string.
Instead I have added max_width to meaning the grouping is always the same size:
x = "ABCDEFGHIJKLIMNOQRSTUVWXYZ"
y = 4
def wrap(string, max_width):
slist = [char for char in string]
new = []
for i in range(0,len(slist),max_width):
new.append(''.join(slist[i:(i+max_width)]))
return new
print(wrap(x, y))
Those earlier posts from #Peter Mason working fine as it just modified 'minimally' original code. However, the original code can be improved further to save a few steps: (the slist = .... is redundant, as string is a character sequence and can be directly index-access)
>>> s = uppers = "ABCDEFGHIJKLIMNOQRSTUVWXYZ"
>>> max_width = 4
>>> newStr = []
>>> for i in range(0, len(s), max_width):
newStr.append(''.join(s[i:i+4]))
>>> newStr
['ABCD', 'EFGH', 'IJKL', 'IMNO', 'QRST', 'UVWX', 'YZ']
>>>
Or, list comprehension:
def wrap(string, max_width):
return [''.join(string[i:i+max_width])
for i in range(0, len(string), max_width)]
>>> wrap(s, 4)
['ABCD', 'EFGH', 'IJKL', 'IMNO', 'QRST', 'UVWX', 'YZ']
>>>

Convert given list to nested list - Python3.x

I have a list in the below format :
input = [['Monday', 'Tuesday', 'Wednesday', '', '1', '2', 'Black', '']]
I would like to convert this to a nested list like below : (See, nested list breaks at null element)
output = [['Monday', 'Tuesday', 'Wednesday'], ['1', '2', 'Black']]
Is there a way to do this? I tried hard to think but could not come up with a solution.
More Examples :
input = [['', 'word1', 'word2', '', '1', '2', 'orange', '']]
output = [['word1', 'word2'],['1', '2', 'orange']]
input = [['', '', 'word1', 'word2', '', '1', '2', 'word3', '', '']]
output = [['word1', 'word2'],['1', '2', 'word3']]
Thanks in advance!!!
That should work:
import itertools
input_ = [['Monday', 'Tuesday', 'Wednesday', '', '1', '2', 'Black', '']]
output = [list(g) for item in input_ for k, g in itertools.groupby(item, bool) if k]
Longer solution:
input_ = [['Monday', 'Tuesday', 'Wednesday', '', '1', '2', 'Black', '']]
output = []
sublist = []
for item in input_:
for subitem in item:
if subitem:
sublist.append(subitem)
continue
if sublist:
output.append(sublist)
sublist = []
Here is a way to do it:
x = [['', '', 'word1', 'word2', '', '1', '2', 'word3', '', '']]
output = []
temp = []
for idx, el in enumerate(x[0]):
if idx == 0 and el == "":
continue
if el != '':
temp.append(el)
elif temp != []:
output.append(temp)
temp = []
Output
[['word1', 'word2'], ['1', '2', 'word3']]

What does the following code say in the simple way?

Can you tell me what this code says in the simple way:
board = [['' for x in range(BOARD_SIZE)] for y in range(BOARD_SIZE)]
This code creates a list of BOARD_SIZE lists. Each of these lists will contain BOARD_SIZE empty strings. So if BOARD_SIZE is 3 then the board will be:
board = [ ['', '', ''],
['', '', ''],
['', '', ''] ]
You can rewrite this code in a single line:
board = [['', '', ''], ['', '', ''], ['', '', '']]

Resources