I am trying to remove a specific indexed list item and haven't been able to figure it out, or any way to make the list less complicated.
a=True
list=[]
costs=[]
while a == True:
Could the list.append()
be an issue?
print('Select from the following list:\n1. Add Item\n2. View Cart\n3. Remove Item\n4. Compute Total\n5. Quit')
choice= int(input('Please enter a number: '))
print()
if choice == 1:
item= input('What item would you like to add? ').capitalize()
cost= float(input(f'What is the cost of the {item}? '))
print(f'{item} has been added to cart.\n')
list.append(f'{item} ' f'${cost:.2f}')
costs.append(cost)
Displays list items line by line as: 1. Bed $120.
Not the biggest fan of the complexity, but it worked.
elif choice == 2:
line= "{{: >{}}}. {{}}\n".format(len(str(len(list))))
for i, item in enumerate(list, start=1):
if len(list) != 0:
print(line.format(i, item))
else:
print('The Cart is Empty\n')
This is supposed to remove a specific index item. This is where I am running into the most issue. I haven't been able to get this to work at all:
elif choice == 3:
print('Which item would you like to remove?')
num=int(input())
if i in list:
list=list.pop(i)
print(f'Item Removed')
else:
print('Invalid Input')
This prints the total of costs:
elif choice == 4:
total=sum(costs)
print(f'Your total is ${total:.2f}\n')
elif choice == 5:
print('Thank you for playing.')
a=False
CodePudding user response:
i in list
tests whetheri
is one of the values in the list, buti
is an index. Useif i < len(list):
list.pop()
returns the element that was removed, not the modified list. So when you dolist = list.pop(i)
, you're replacing the list with the removed element. You should just calllist.pop(i)
without assigning back to the variable, it modifies the list in place.
elif choice == 3:
print('Which item would you like to remove?')
num=int(input())
if i < len(list):
list.pop(i)
print(f'Item Removed')
else:
print('Invalid Input')
Also, you shouldn't use list
as a variable name, since it's the name of a built-in class.
CodePudding user response:
In python lists, some methods return a new list, but others change the existing list and don't return anything.
list.pop
is removing the right element and returning it: if you assign it to your list, your variable becomes the element, not the list.
So you should invoke the method, and ignore its return:
lst = ["a", "b", "c"]
print(lst)
lst.pop(0)
print(lst)
python main.py
['a', 'b', 'c']
['b', 'c']
If you don't need the element, you can also use del
:
lst = ["a", "b", "c"]
print(lst)
del lst[0]
print(lst)
CodePudding user response:
You have some options. First, be sure not to use list
as a variable name - list
is a built-in class and 'shadowing' that name will cause unexpected behavior.
To remove an item from a list you can do the following (in the REPL):
>>> ls = [1,2,3]
>>> ls.remove(2)
>>> ls
[1, 3]
This removes by value. That is, it looks for the first matching value and removes it. This value is not returned, and the list is modified in-place.
If you want to remove by index, you can use pop()
:
>>> ls = [1,2,3]
>>> x = ls.pop(0)
>>> x
1
>>> ls
[2, 3]
This removes the element at the provided index (in this case index 0
), and returns the element. This list is modified in-place.
You can use the [del][2]
keyword:
>>> ls = [1,2,3]
>>> del ls[1]
>>> ls
[1, 3]
This deletes the referenced object and removes it from the list in place.
An idiomatic way of doing what you're looking for is this:
ls = ... # Define your list
print('Which item would you like to remove?')
item_idx = int(input())
item = ls.pop(item_idx) if item_idx < len(ls) else None # First do the task
if item is None: # Then report what the result is
print("Invalid item.")
else:
print(f"Item removed: {}")
Noting that the item_idx
is being compared against the list length, not whether it is in the list (i.e. item_idx in ls
). I'm stressing the naming of the variables here, because it helps to think clearly about what is actually happening under the hood.
Finally, a note on the 'complexity' of string formatting. You can probably achieve a similar effect to line= "{{: >{}}}. {{}}\n".format(len(str(len(list))))
with:
for idx, item in enumerate(ls):
print(f"{idx:>4} item")
This left-aligns, and assumes you have fewer than ten thousand items, but that should probably make it clearer to the reader of the code what is going on without impacting the output poorly.