How to make a nested list in python - python-3.x

Suppose I have a 2 lists in my python script:
my_list = ['hat', 'bat']
other_list = ['A', 'B', 'C']
I want to iterate through other_list and create a nested list for 'bat's that adds '_' + other_list item to a the 'bat' and puts it in a nested list:
for item in other_list:
for thing in my_list:
if thing == 'bat':
print(thing + '_' + item)
My desired outcome would be new_list = ['hat',['bat_A', 'bat_B', 'bat_C']]
How would I achieve this?
I tried the below, but it produces this: ['hat', 'hat', 'hat', ['bat_A', 'bat_B', 'bat_C']]
new_list = []
extra = []
for item in other_list:
for thing in my_list:
if thing == 'bat':
extra.append(thing + '_' + item)
else:
new_list.append(thing)
new_list.append(extra)

Try this:
>>> my_list = ['hat', 'bat']
>>> other_list = ['A', 'B', 'C']
>>> new_list=[my_list[0], [f'{my_list[1]}_{e}' for e in other_list]]
>>> new_list
['hat', ['bat_A', 'bat_B', 'bat_C']]
If your question (which is a little unclear) is just about reacting to 'bat' with a different reaction, you can do this:
my_list = ['hat', 'bat','cat']
other_list = ['A', 'B', 'C']
new_list=[]
for e in my_list:
if e=='bat':
new_list.append([f'{e}_{x}' for x in other_list])
else:
new_list.append(e)
>>> new_list
['hat', ['bat_A', 'bat_B', 'bat_C'], 'cat']
Which can be reduced to:
>>> [[f'{e}_{x}' for x in other_list] if e=='bat' else e for e in my_list]
['hat', ['bat_A', 'bat_B', 'bat_C'], 'cat']

I think will work
my_list = ['hat', 'bat']
other = ['A', 'B' , 'C']
new_list = []
extra = []
for item in my_list:
if item == 'bat':
for char in other:
extra.append(item + '_' + char)
else:
new_list.append(item)
new_list.append(extra)
print(new_list)

OK, this is just my answer, but it seems to work. I think is clunky though, and I'm hoping for a better answer
my_list = ['hat', 'bat']
other_list = ['A', 'B', 'C']
new_list = []
extra = []
for item in other_list:
for thing in my_list:
if thing == 'bat':
extra.append(thing + '_' + item)
else:
if thing not in new_list:
new_list.append(thing)
new_list.append(extra)

Related

How to remove elements from python class list

I am learning python oops. I am trying to remove an object (trying to remove all the student with mid = 1)from a class list.
for example -
stdents = [[[1], 'y', 'r'], [[2, 3], 'y', 'w'], [[1], 'z', 'r']]
I want to remove all id which contains 1.
here is my code -
class StudentTable:
def _init_(self, idList, name, state):
self.idList = []
self.name = name
self.state = state
stdents = []
student = StudentTable([1], 'y', 'r')
stdents.append(student)
student = StudentTable([2, 3], 'y', 'w')
stdents.append(student)
student = StudentTable([1], 'z', 'r')
stdents.append(student)
print(stdents[0].name)
print(stdents[1].name)
print(stdents[2].name)
mid = 1
for i in range(len(stdents)):
if mid in stdents[i].idList:
# del stdents[i]
stdents.remove(mid)
print(stdents)
But it's not removing.
Even I tried del but not working.
Can anyone please help me to resolve this issue?
Thanks in advance,
Khush
actually there is a simple mistake in line 3.
it should be self.idList = idList instead of self.idList = []
class StudentTable:
def __init__(self, idList, name, state):
self.idList = idList
self.name = name
self.state = state
stdents = []
student1 = StudentTable([1], 'a', 'r')
stdents.append(student1)
student2 = StudentTable([3], 'b', 'w')
stdents.append(student2)
student3 = StudentTable([1], 'c', 'r')
stdents.append(student3)
#print(stdents[0].name)
#print(stdents[1].name)
#print(stdents[2].name)
mid = 1
for i in (stdents):
#print(i.idList,i)
if mid in i.idList:
stdents.remove(i)
print(stdents)

The problem of using {}.fromkey(['k1','k2'],[]) and {'k1':[],'k2':[]}

list1 = [99,55]
dict1 = {'k1':[],'k2':[]}
for num in list1:
if num > 77:
dict1['k1'].append(num)
else:
dict1['k2'].append(num)
print(dict1)
{'k1':[99],'k2':[55]}
But when I replaced dict1 = {'k1':[],'k2':[]} to {}.fromkeys(['k1','k2'],[]) , the result became {'k1': [99, 55], 'k2': [99, 55]}
why this happens? I really have no idea.
This happens because you are passing the same list object to both keys. This is the same situation as when you create an alias for a variable:
a = []
b = a
a.append(55)
b.append(99)
print(b)
prints [55, 99] because it is the same list instance.
If you want to make it more concise from a list of keys to initialize with empty list, you can do this:
dict1 = {k: [] for k in ('k1', 'k2')}
This will create a new list instance for every key.
Alternatively, you can use defaultdict
from collections import defaultdict
list1 = [99,55]
dict1 = defaultdict(list)
for num in list1:
if num > 77:
dict1['k1'].append(num)
else:
dict1['k2'].append(num)
print(dict1)
Also works.
The fromKeys() can also be supplied with a mutable object as the default value.
if we append value in the original list, the append takes place in all the values of keys.
example:
list1 = ['a', 'b', 'c', 'd']
list2 = ['SALIO']
dict1 = dict.fromkeys(list1, list2)
print(dict1)
output:
{'a': ['SALIO'], 'b': ['SALIO'], 'c': ['SALIO'], 'd': ['SALIO']}
then you can use this:
list1 = ['k1', 'k2']
dict1 = {'k1':[],'k2':[]}
list2 =[99,55]
for num in list2:
if num > 77:
a = ['k1']
dict1 = dict.fromkeys(a, [num])
else:
b = ['k2']
dict2 = dict.fromkeys(b,[num] )
res = {**dict1, **dict2}
print(res)
output:
{'k1': [99], 'k2': [55]}
You can also use the python code to merge dict code:
this function:
def Merge(dict1, dict2):
return(dict2.update(dict1))
then:
print(Merge(dict1, dict2)) #This return None
print(dict2) # changes made in dict2

How can I split a text file with # as separator and then split the lines inside the separated part?

I have a text file that have a pattern like
#
a,b
c,d
#
e,f
g,h
I want the result to print as each block separated is an element and each line in the block is a sub-element to the block one
[[[a, b], [c, d]], [[e, f], [g, h]]]
Here is my code, any suggestion from here to get the result ? Thanks
ret_list = []
a = open(file_name,'r')
content = a.read()
content = content.split('#')
for l in content:
l = l.strip().split('\n')
for elem in l:
temp = []
elem = elem.split(',')
if '' not in elem:
temp.append(elem)
ret_list.append(temp)
a.close()
And the result I got
[[], [['a', 'b']], [['c', 'd']], [['e', 'f']], [['g', 'h']]]
You're creating temp = [] for every line - but you want to create it for every "block" - so you move it outside of the inner for loop. (same for the ret_list.append())
content = content.split('#')
for l in content:
l = l.strip().split('\n')
temp = []
for elem in l:
elem = elem.split(',')
if '' not in elem:
temp.append(elem)
ret_list.append(temp)
This gives you
[[], [['a', 'b'], ['c', 'd']], [['e', 'f'], ['g', 'h']]]
You could add a check that temp is not empty before appending.
if temp:
ret_list.append(temp)
Another way to avoid the leading empty "block" is to strip before splitting
content.strip('#').split('#')
Finally, this is how I would write it.
ret_list = []
for block in content.strip('#').split('#'):
lines = block.strip().splitlines()
lines = [ line.split(',') for line in lines ]
ret_list.append(lines)
for l in content:
l = l.strip().split('\n')
k=[]
for elem in l:
temp=[]
elem = elem.split(',')
if '' not in elem:
temp.append(elem)
k=k+temp
if k!=[]:
ret_list.append (k)
print (ret_list)
i created new list k to store a block with two block i.e [['a', 'b'], ['c', 'd']] and then added to ret_list if k list is not empty
output
[[['a', 'b'], ['c', 'd']], [['e', 'f'], ['g', 'h']]]

How to replace list element with string without double quotes?

I have a simple list like this:
list = ['A','B','C']
and to replace element #1 of l1 with this string:
str = "'W','T'"
I'm doing like this:
>>> list[1] = str
>>> list
['A', "'W','T'", 'C']
How can I do to replace list[1] values with str content without the double quotes? like this:
['A','W','T','C']
You can't insert it directly like that. You need to clean it first and convert it to a list and use slicing.
list1 = ['A','B','C']
str1 = "'W','T'"
new_list = [a.strip("'") for a in str1.split(",")]
list1 = list1[:1] + new_list + list1[2:]
print(list1) # ['A', 'W', 'T', 'C']
I also modified your variable names because list and str are reserved keywords.
You have to put the elements of the string into a list and then add the list elements to the desired position in your destination list.
list_ = ['A', 'B', 'C']
string = "'W','T'"
formatted = [letter for letter in string if letter.isalpha()]
i = 1 #index of element to replace
list_[i:(i + len(formatted))-1] = formatted
print(list_)
list[item] = str(list[item])
>>> mylist = [1,3,5]
>>> mylist[0] = str(mylist[0])
>>> mylist
['1', 3, 5]
>>>

Inserting list into another list using loops only:

I'm using the current version of python. I need to return a copy of list1 with list2 inserted at the position indicated by index i.e if the index value is 2, list2 is inserted into list 1 at position 2. I can only use for/while loops, the range function & the list_name.append (value) methods and the lists cannot be sliced. So if list1 list1 = boom list2 = red and the index value = 2, how do I return a new list = boredom? I have this so far:
list1 = ['b','o','o','m']
list2 = ['r','e','d']
index = 2
new_list = []
if index > len(list1):
new_list = list1 + list2
print (new_list)
if index <= 0:
new_list = list2 + list1
print (new_list)
An alternative approach to Padriac's - using three for loops:
list1 = ['b','o','o','m']
list2 = ['r','e','d']
n = 2
new_list = []
for i in range(n): # append list1 until insert point
new_list.append(list1[i])
for i in list2: # append all of list2
new_list.append(i)
for i in range(n, len(list1)): # append the remainder of list1
new_list.append(list1[i])
Once you hit the index, use an inner loop to append each element from list2:
for ind, ele in enumerate(list1):
# we are at the index'th element in list1 so start adding all
# elements from list2
if ind == index:
for ele2 in list2:
new_list.append(ele2)
# make sure to always append list1 elements too
new_list.append(ele)
print(new_list)
['b', 'o', 'r', 'e', 'd', 'o', 'm']
If you must use range just replace enumerate with range:
new_list = []
for ind in range(len(list1)):
if ind == index:
for ele2 in list2:
new_list.append(ele2)
new_list.append(list1[ind])
print(new_list)
['b', 'o', 'r', 'e', 'd', 'o', 'm']
Or without ifs using extend and remove if allowed:
new_list = []
for i in range(index):
new_list.append(list1[i])
list1.remove(list1[i])
new_list.extend(list2)
new_list.extend(list1)
Appending as soon as we hit the index means the elements will be inserted from the correct index, the elements from list1 must always be appended after your if check.
Check out this small snippet of code I've written.
Check the while condition that is used. I hope it will answer your question.
email = ("rishavmani.bhurtel#gmail.com")
email_split = list(email)
email_len = len(email)
email_uname_len = email_len - 10
email_uname = []
a = 0
while (a < email_uname_len):
email_uname[a:email_uname_len] = email_split[a:email_uname_len]
a = a + 1
uname = ''.join(email_uname)
uname = uname.replace(".", " ")
print("Possible User's Name can be = %s " %(uname))

Resources