Nibaga
Nibaga

Reputation: 25

How to remove one item in this list?

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

Answers (3)

Mulan
Mulan

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

Chris
Chris

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

bigblind
bigblind

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

Related Questions