How do I pop() from a list without using pop()? - python

I have a function called pop_item() that I am trying to make act like a pop() that works with the list class, how would I do that, here is my code:
def empty(lst):
return lst == []
def pop_item(lst):
lst = lst[::-1]
new_lst = []
for i in lst:
if i != lst[-1]:
new_lst += [i]
lst = new_lst
return lst
def main():
todo = [1,2,3,4]
print(todo) #prints [1,2,3,4] as expected
print('\n' + 75 * '_' + '\n')
print(pop_item(todo)) #pop the item off
print(todo) #output should then be [1,2,3]
if __name__ == '__main__':
main()
Note: I am not allowed to use any built in functions eg len(),index,del() etc.

Here are a few variants of popping items from a list without using list functions, only slicing & list comprehension
pop the last item using slicing & slicing assignment:
def pop_item(lst):
lst[:] = lst[:-1]
pop a valued item (last one but can be a parameter) by rebuilding the list & slice assign
def pop_item(lst):
lst[:] = [x for x in lst if x!=lst[-1]]
(that can pop other items in the list if they have the same value)
by speciftying item position/index in the list:
def pop_item(lst,item_position):
lst[:] = [x for i,x in enumerate(lst) if i!=item_position]

Related

Not empty list is out of index on list[0]

I'm doing this problem on Leetcode: https://leetcode.com/problems/merge-two-sorted-lists/description/
I came up with this solution:
class Solution(object):
def mergeTwoLists(self, list1, list2):
x = list1
y = list2
listx = []
listy = []
while x != None and y != None:
if x != None:
listx.append(x.val)
x = x.next
if y != None:
listy.append(y.val)
y = y.next
listz = []
listz.extend(listx)
listz.extend(listy)
listz.sort()
resultlist = []
for i in range(len(listz)):
resultlist.append(ListNode(listz[i]))
for x in reversed(range(len(resultlist)-1)):
resultlist[x].next = resultlist[x+1]
result = resultlist[0]
return result
Explanation of the code:
from the input(ListNode) create two lists
merge the lists into one list and sort it
create a list of ListNodes(resultlist) "create nodes"
create the return ListNode splicing all the nodes from result nodes
This code should work but when I try to run it, it gives me this error:
IndexError: list index out of range result = resultlist[0]"
even though the list isn't empty and it contains an element on the index 0.
How can I solve this?
This exercise is all about how you navigate a singly linked list. Building lists and reconstructing the linked list is not a great idea.
The problem in the code shown in the question comes about due to lack of checking against edge cases.
This will perform better and will be more robust:
class Solution():
def mergeTwoLists(self, list1, list2):
cln = ListNode()
dln = cln
while list1 and list2:
if list1.val < list2.val:
cln.next = list1
list1, cln = list1.next, list1
else:
cln.next = list2
list2, cln = list2.next, list2
if list1 or list2:
cln.next = list1 if list1 else list2
return dln.next
If both list1 and list2 are empty then your resultlist will be empty too (there will be no element at index 0) so check at the start of your method if both lists are empty if yes then return list1 or list2
if not (list1 and list2): return list1
and I think your result will some fail test cases.
Please check for edge cases and you can make this code more simple if you use link list and do not use python list
All the best!!!

python list of lists contain substring

I have the list_of_lists and I need to get the string that contains 'height' in the sublists and if there is no height at all I need to get 'nvt' for the whole sublist.
I have tried the following:
list_of_lists = [['width=9','length=3'],['width=6','length=4','height=4']]
_lists = []
for list in list_of_lists:
list1 = []
for st in list:
if ("height" ) in st:
list1.append(st)
else:
list1.append('nvt')
_lists.append(list1)
OUT = _lists
the result I need to have is :
_lists = ['nvt', 'height=4']
what I'm getting is:
_lists = [['nvt','nvt'],['nvt','nvt','height=4']]
This is a good case for implementing a for/else construct as follows:
list_of_lists = [['width=9','length=3'],['width=6','length=4','height=4']]
result = []
for e in list_of_lists:
for ss in e:
if ss.startswith('height'):
result.append(ss)
break
else:
result.append('nvt')
print(result)
Output:
['nvt', 'height=4']
Note:
This could probably be done with a list comprehension but I think this is more obvious and probably has no significant difference in terms of performance
This should work, you can assign height variable to first value in the sublist where s.startswith("height") is True, and if nothing matches this filter, you can assign height to 'nvt'.
_lists = []
for sublist in list_of_lists:
height = next(filter(lambda s: s.startswith("height"), sublist), 'nvt')
_lists.append(height)
And if you wish to be crazy, you can use list comprehension to reduce the code to the:
_lists = [next(filter(lambda s: s.startswith("height"), sublist), 'nvt') for sublist in list_of_lists]
Try this (Python 3.x):
import re
list_of_lists = [['width=9','length=3'],['width=6','length=4','height=4']]
_lists = []
r = re.compile("height=")
for li in list_of_lists:
match = list(filter(r.match, li))
if len(match) > 0:
_lists.extend(match)
else:
_lists.append('nvt')
OUT = _lists
print(OUT)

How to extract the first element (as a list of string) of the n-th elements of a nested list, Python

I am a fresh python beginner and trying to extract the first element of the first n-th elements of a nested list. But it doesn't work so far.
Say:
list = [["Anna","w",15],["Peter","m",20],["Zani","m",10], ["Lily","w",19]]
Goal:
list_new = ['Anna','Peter','Zani'...(#until the n-th elements)]
If I want to first element of all the elements in the list, it should be:
for i in list:
for j in i:
print j[0]
But what if i only want to strip the first element of the n-th elements of the list, instead of all the elements.
For example for the first 2 elements:
I tried:
for i in list[0:2]:
for j in i:
print j[0]
but it didn't work.
What's more, if i want to give the value of n later by using
def sheet(list, n)
and the return statement, how could i do it?
Thank you very much!!
lst = [["Anna","w",15],["Peter","m",20],["Zani","m",10], ["Lily","w",19]]
n = 2
print(lst[n][0])
Output:
Zani
---Updated answer for the details added in the question---
l = [["Anna","w",15],["Peter","m",20],["Zani","m",10], ["Lily","w",19]]
n = 2
for i in range(n):
print(l[i][0])
Output:
Anna
Peter
You can use a list comprehension. Given an input list of lists L:
L_new = [i[0] for i in L[:n]]
Functionally, you can use operator.itemgetter. In addition, you can use itertools.islice to avoid creating an intermediary list:
from operator import itemgetter
from itertools import islice
L_new = list(map(itemgetter(0), islice(L, 0, n)))
Be careful, list is reserved for the built-in function list() in python, you should not use 'list' as variable name.
To get the first element of each nested list :
l = [["Anna","w",15],["Peter","m",20],["Zani","m",10], ["Lily","w",19]]
for e in l:
print(e[0])
Prints :
Anna
Peter
Zani
Lily
To do the same on the nth first elements :
def sheet(l, n):
return [e[0] for e in l[:n]]
sheet(l, 3)
Returns
['Anna', 'Peter', 'Zani']
EDIT
def sheet(l, n):
for e in l[:n]
return [e[0]]
This code only returns ['Anna'] because the return statement stops the function. The for loop is stopped at the first element.
def sheet(l, n):
return [e[0] for e in l[:n]]
is equivalent to :
def sheet(l, n):
result = [e[0] for e in l[:n]]
return result
which is equivalent to :
def sheet(l, n):
result = []
for e in l[:n]:
result.append(e[0])
return result
The for loop can ends before the return statement.
More informations here.
Just try this one which will be easier for you to understand:
n = int(input())
lst = [["Anna","w",15],["Peter","m",20],["Zani","m",10], ["Lily","w",19]]
lst_new = []
for item in lst[:n]:
name, *rest = item
lst_new.append(name)

cycle "for" in Python

I have to create a three new lists of items using two different lists.
list_one = ['one', 'two','three', 'four','five']
list_two = ['blue', 'green', 'white']
So, len(list_one) != len(list_two)
Now I should create an algorithm(a cycle) which can do this:
[oneblue, twoblue, threeblue, fourblue, fiveblue]. Same for 'green' and 'white'.
I undestand that I should create three cycles but I don't know how.
I've tried to make a function like this but it doesn't works.
def mix():
i = 0
for i in range(len(list_one)):
new_list = list_one[i]+list_two[0]
i = i+1
return new_list
What am I doing wrong?
I think you might be looking for itertools.product:
>>> [b + a for a,b in itertools.product(list_two, list_one)]
['oneblue',
'twoblue',
'threeblue',
'fourblue',
'fiveblue',
'onegreen',
'twogreen',
'threegreen',
'fourgreen',
'fivegreen',
'onewhite',
'twowhite',
'threewhite',
'fourwhite',
'fivewhite']
You should do this
def cycle(list_one,list_two):
newList = []
for el1 in list_two:
for el2 in list_one:
newList.append(el2+el1)
return newList
There are a few problems with your code:
When you do a for loop for i in ...:, you do not need to initialize i (i = 0) and you should not increment it (i = i + 1) since Python knows that i will take all values specified in the for loop definition.
If your code indentation (indentation is very important in Python) is truly the one written above, your return statement is inside the for loop. As soon as your function encounters your return statement, your function will exit and return what you specified: in this case, a string.
new_list is not a list but a string.
In Python, you can loop directly over the list items as opposed to their index (for item in list_one: as opposed to for i in range(len(list_one)):
Here is your code cleaned up:
def mix():
new_list = []
for i in list_one:
new_list.append(list_one[i]+list_two[0])
return new_list
This can be rewritten using a list comprehension:
def mix(list_one, list_two):
return [item+list_two[0] for item in list_one]
And because list_two has more than one item, you would need to iterate over list_two as well:
def mix(list_one, list_two):
return [item+item2 for item in list_one for item2 in list_two]
return should be out of for loop.
No need to initialize i and increment it, since you are using range.
Also, since both list can be of variable length, don't use range. Iterate over the list elements directly.
def mix(): should be like def mix(l_one,l_two):
All above in below code:
def mix(l_one,l_two):
new_list = []
for x in l_one:
for y in l_two:
new_list.append(x+y)
return new_list
list_one = ['one', 'two','three', 'four','five']
list_two = ['blue', 'green', 'white']
n_list = mix(list_one,list_two)
print n_list
Output:
C:\Users\dinesh_pundkar\Desktop>python c.py
['oneblue', 'onegreen', 'onewhite', 'twoblue', 'twogreen', 'twowhite', 'threeblu
e', 'threegreen', 'threewhite', 'fourblue', 'fourgreen', 'fourwhite', 'fiveblue'
, 'fivegreen', 'fivewhite']
C:\Users\dinesh_pundkar\Desktop>
Using List Comprehension, mix() function will look like below:
def mix(l_one,l_two):
new_list =[x+y for x in l_one for y in l_two]
return new_list

Nested lists python

Can anyone tell me how can I call for indexes in a nested list?
Generally I just write:
for i in range (list)
but what if I have a list with nested lists as below:
Nlist = [[2,2,2],[3,3,3],[4,4,4]...]
and I want to go through the indexes of each one separately?
If you really need the indices you can just do what you said again for the inner list:
l = [[2,2,2],[3,3,3],[4,4,4]]
for index1 in xrange(len(l)):
for index2 in xrange(len(l[index1])):
print index1, index2, l[index1][index2]
But it is more pythonic to iterate through the list itself:
for inner_l in l:
for item in inner_l:
print item
If you really need the indices you can also use enumerate:
for index1, inner_l in enumerate(l):
for index2, item in enumerate(inner_l):
print index1, index2, item, l[index1][index2]
Try this setup:
a = [["a","b","c",],["d","e"],["f","g","h"]]
To print the 2nd element in the 1st list ("b"), use print a[0][1] - For the 2nd element in 3rd list ("g"): print a[2][1]
The first brackets reference which nested list you're accessing, the second pair references the item in that list.
You can do this. Adapt it to your situation:
for l in Nlist:
for item in l:
print item
The question title is too wide and the author's need is more specific. In my case, I needed to extract all elements from nested list like in the example below:
Example:
input -> [1,2,[3,4]]
output -> [1,2,3,4]
The code below gives me the result, but I would like to know if anyone can create a simpler answer:
def get_elements_from_nested_list(l, new_l):
if l is not None:
e = l[0]
if isinstance(e, list):
get_elements_from_nested_list(e, new_l)
else:
new_l.append(e)
if len(l) > 1:
return get_elements_from_nested_list(l[1:], new_l)
else:
return new_l
Call of the method
l = [1,2,[3,4]]
new_l = []
get_elements_from_nested_list(l, new_l)
n = [[1, 2, 3], [4, 5, 6, 7, 8, 9]]
def flatten(lists):
results = []
for numbers in lists:
for numbers2 in numbers:
results.append(numbers2)
return results
print flatten(n)
Output: n = [1,2,3,4,5,6,7,8,9]
I think you want to access list values and their indices simultaneously and separately:
l = [[2,2,2],[3,3,3],[4,4,4],[5,5,5]]
l_len = len(l)
l_item_len = len(l[0])
for i in range(l_len):
for j in range(l_item_len):
print(f'List[{i}][{j}] : {l[i][j]}' )

Categories

Resources