MJP
MJP

Reputation: 1597

returning elements from a list in python

Suppose I have a list called a =['apple' 'anachi', 'butter' 'bread', 'cat' , 'catre']

I need to return elements as follows:

a['a'] should return [apple, anachi]
a['b'] should return ['butter', 'bread']

How do I do this in python

Upvotes: 0

Views: 2221

Answers (4)

Hackaholic
Hackaholic

Reputation: 19733

Using itertools.groupby:

>>> my_dict = {}
>>> for x,y in itertools.groupby(a, key=lambda x:x[0]):
...     my_dict[x] = my_dict.get(x,[]) + list(y)
...
>>> my_dict['a']
['apple', 'anachi']
>>> my_dict['b']
['butter', 'bread']
>>> my_dict['c']
['cat', 'catre']

Upvotes: 0

jedwards
jedwards

Reputation: 30200

You have a lot of options here.

First, note the behavior of your list currently:

a =['apple' 'anachi', 'butter' 'bread', 'cat' , 'catre']
print a[0]  # appleanachi
print a[1]  # butterbread

Since you're missing commas between "apple" and "anachi", and "butter" and "bread", they're being concatenated. I'm not sure that's what you want.

If you correct that to make it a "flat" list, you could extract elements from the list with the slicing syntax, but you would need to know the indices to do this:

a = ['apple', 'anachi', 'butter', 'bread', 'cat' , 'catre']
print a[0:2]  # ['apple', 'anachi']
print a[2:4]  # ['butter', 'bread']

Alternatively, you could use nested lists, then you wouldn't need the slicing syntax, just a single index of the "pair":

a = [['apple', 'anachi'], ['butter', 'bread'], ['cat' , 'catre']]
print a[0]  # ['apple', 'anachi']
print a[1]  # ['butter', 'bread']

All of these approaches so far required that you knew the index, but if you don't, and you want to extract elements from the list that have a certain prefix/start with a certain letter combination, you could do something like:

def search(lst, pre):
    return [e for e in lst if e.startswith(pre)]

a = ['apple', 'anachi', 'butter', 'bread', 'cat' , 'catre']
print search(a, 'a')  # ['apple', 'anachi']
print search(a, 'b')  # ['butter', 'bread']

This search approach could also be implemented for a nested list as well, for example if you wanted to find all the "pairs" where the first item of the pair started with the given prefix:

def search(lst, pre):
    return [p for p in lst if p[0].startswith(pre)]

a = [['apple', 'anachi'], ['butter', 'bread'], ['cat' , 'catre']]
print search(a, 'a')  # [['apple', 'anachi']]
print search(a, 'b')  # [['butter', 'bread']]

Upvotes: 1

William Gaul
William Gaul

Reputation: 3181

What I would do is implement a custom sequence:

from collections import Sequence

class MyList(Sequence):

    def __init__(self, data=()):
        super(MyList, self).__init__()
        self._list = list(data)

    def __getitem__(self, key):
        if type(key) == int:
            return self._list[key]
        return [e for e in self._list if e.startswith(key)]

    def __len__(self):
        return len(self._list)


a = MyList(['apple', 'anachi', 'butter', 'bread', 'cat' , 'catre'])

print a['a']  # prints ['apple', 'anachi']
print a['b']  # prints ['butter', 'bread']
print a['ca']  # prints ['cat' , 'catre']

Here the crucial part is the custom __getitem__, where instead of simply returning the item from the underlying list self._list, we return a new list of items from self._list that start with the given key.

Note that the code above has no error handling (for example you need to check that the elements are only strings for this to work).

Upvotes: 0

halex
halex

Reputation: 16403

If you only want to access your list of names a by the first character and don't mind that it won't be a list anymore I have the following solution for you:

>>> from collections import defaultdict
>>> a =['apple', 'anachi', 'butter', 'bread', 'cat' , 'catre']
>>> d=defaultdict(list)
>>> for s in a:
    d[s[0]].append(s)


>>> a=d
>>> a['a']
['apple', 'anachi']
>>> a['b']
['butter', 'bread']

Upvotes: 4

Related Questions