Reputation: 25
Suppose I have 2 lists
list1 = [['abc', '123'], ['def', '456']]
list2 = ['abc','123','def','456','ghi','789']
How can I remove 1 element from list1 by typing only the letters or the number
For example if I type 'abc' OR '123' I want it to display
[['def', '456'], ['ghi', '789']]
in list2 I can make it remove the pair by the following code
contact = input("Type the name/number of the contact you want to remove")
if contact in list2:
pos = list2.index(contato)
if pos % 2 == 0:
list2.pop(pos)
list2.pop(pos)
if pos % 2 != 0:
list2.pop(pos-1)
list2.pop(pos-1)
However I wouldn't be able to do that in list1 as both number and letters are together so the I guess the only way would be to transfer the new list2 to list1 but I'm not sure how I would do that
I know what I wrote is really confusing, but basically I want to transform
this: ['def','456','ghi','789'] into this: [['def', '456'], ['ghi', '789']]
Upvotes: 0
Views: 97
Reputation: 135217
It seems like you're coming to python from another language. I'm going to recommend a list of tuples for your final data, but can change that to a list of of lists if you like that better
I'll start with a function that converts your flat list in to a list of 2-element tuples, called make_phonebook
. Then we will make a filter_phonebook
function which takes a phonebook and an input query
, and returns a new phonebook where entries that matched the input query are removed
def make_phonebook(iterable):
z = iter(iterable)
return [(x,y) for x,y in zip(z,z)]
def filter_phonebook(phonebook, query):
return [(name,phone)
for name,phone in phonebook
if name != query and phone != query]
Now we can very easily work with the data
list2 = ['abc','123','def','456','ghi','789']
book = make_phonebook(list2)
print(filter_phonebook(book, 'abc'))
# [('def', '456'), ('ghi', '789')]
print(filter_phonebook(book, '123'))
# [('def', '456'), ('ghi', '789')]
print(filter_phonebook(book, 'def'))
# [('abc', '123'), ('ghi', '789')]
Upvotes: 0
Reputation: 22953
I know what I wrote is really confusing, but basically I want to transform
this: ['def','456','ghi','789'] into this: [['def', '456'], ['ghi', '789']]
Use a simple list comprehension to nest the list at every two elements:
>>> l = ['def','456','ghi','789']
>>> l = [[i, j] for i, j in zip(l[0::2], l[1::2])]
>>> l
[['def', '456'], ['ghi', '789']]
>>>
What this does is it iterates through the list by every two elements. This only works however if the list are the same length. This would break:
>>> l = ['def','456','ghi','789', 'foo']
>>> l = [[i, j] for i, j in zip(l[0::2], l[1::2])]
>>> l
[['def', '456'], ['ghi', '789']]
>>>
The problem, is the builtin zip()
stops at the shortest iterable. If you need to group a list that can have uneven length, use itertools.zip_longest()
. It will fill None
into any unmatched values:
>>> from itertools import zip_longest # izip_longest for Python 2.x users
>>> l = ['def','456','ghi','789', 'foo']
>>> l = [[i, j] for i, j in zip_longest(l[0::2], l[1::2])]
>>> l
[['def', '456'], ['ghi', '789'], ['foo', None]]
>>>
Upvotes: 2
Reputation: 12867
What about:
contact = input("Type the name/number of the contact you want to remove")
for i in range(len(list1)):
pair = list1[i]
if contact in pair:
list1.pop(pair)
What this does, is loop through numbers from 0 to len(list1)
, which are the indices for all the items in list1
. If the item at that index contains the typed contact, pop it from list1
.
As @leaf's answer suggests, you can also do this using list comprehension.
contact = input("Type the name/number of the contact you want to remove")
result = [pair for pair in list1 if contact not in pair]
This does basically the same thing as the code above, but in a slightly different way. The brackets [ ... ]
indicate you're creating a new list. The expression between these brackets specifies what should go in the list.
The part that goes for pair in list1
looks familiar, right? It's basically a for
loop that loops over the elements in list1
, assigning each item in turn to the pair
variable.
But the expression we have here is slightly different, it starts with: pair for pair in list1
. That first pair
is an expression that specifies what you want to put in the resulting list, for each iteration of the loop. In this case, we're just putting the pair straight into the resulting list, but you can modify it here. Let's say you just wanted to put the first element of each pair in the resulting list, then you'd write:
result = [pair[0] for pair in list1]
So what's that last part about? That if contact not in pair
part specifies that only pairs that don't include contact
should be put into our new list. You could put any expression there, and any time that expression evaluates to True
, the item would be included in the result.
Upvotes: 1