Python: Получить предметы на глубине? (установить библиотеку?) - PullRequest
1 голос
/ 10 апреля 2010

У меня есть вложенный список примерно так:

PLACES = (
    ('CA', 'Canada', (
        ('AB', 'Alberta'),
        ('BC', 'British Columbia' (
            ('van', 'Vancouver'),
        ),
        ...
    )),
    ('US', 'United States', (
        ('AL', 'Alabama'),
        ('AK', 'Alaska'),
        ...

Мне нужно извлечь из него некоторые данные. Если depth равно 0, мне нужно получить все страны (и их коды), если depth == 1, мне нужно получить все штаты / провинции, если depth == 2, мне нужно получить все города ... и так далее. Есть ли какая-то библиотека для таких вещей? Или кто-то может указать мне правильное направление? Я начал кодировать решение только для того, чтобы понять, что оно не будет работать для уровней глубже 1, потому что вы должны входить и выходить из каждого списка ...

Также обратите внимание, что не у всех предметов есть 3-я часть (то есть мы притворяемся, что у Альберты нет городов, поэтому при извлечении предметов на глубине 2 в этом ограниченном сценарии просто вернется ('van','Vancouver')).


Я не осознавал этого раньше, но мне также нужно было родительское значение. Итак, я изменил решение Interjay:

def depth_gen(seq, depth, par=None):
    if depth==0:
        for x in seq:
            yield par, x[0], x[1] 
        return

    for x in seq:
        if len(x)==3:
            par = x[0]
            for y in depth_gen(x[2], depth-1, par):
                yield y

который я использую для генерации HTML:

<label for="id-pickup_address-province">Province</label>
<select id="id-pickup_address-province" rel="pickup_address-country" name="pickup_address-province">
    <option rel="CA" value="AB">Alberta</option>
    <option rel="CA" value="BC">British Columbia</option>
    <option rel="CA" value="MB">Manitoba</option>
    ...
    <option rel="US" value="WV">West Virginia</option>
    <option rel="US" value="WI">Wisconsin</option>
    <option rel="US" value="WY">Wyoming</option>
</select>
<label for="id-pickup_address-country">Country</label>
<select id="id-pickup_address-country" name="pickup_address-country">
    <option value="CA">Canada</option>
    <option value="US">United States</option>
</select>

И тогда я смогу легко фильтровать список с помощью jQuery, основываясь на том, какая страна выбрана ...

Ответы [ 3 ]

5 голосов
/ 10 апреля 2010

Вот решение, которое будет работать на любой глубине:

def depthGenerator(seq, depth):
    if depth==0:
        for x in seq:
            yield x[:2] #strip subsequences
        return

    for x in seq:
        if len(x)==3:   #has subsequence?
            for y in depthGenerator(x[2], depth-1):
                yield y

Пример:

>>> list(depthGenerator(PLACES, 1))
[('AB', 'Alberta'), ('BC', 'British Columbia'), ('AL', 'Alabama'), ('AK', 'Alaska')]
1 голос
/ 10 апреля 2010

Предложение, не используйте вложенные списки. Создайте реальную структуру классов, которая даст вам больше информации и организации. Это облегчит думать, облегчит кодирование и облегчит чтение другими людьми.

1 голос
/ 10 апреля 2010

Вот что я вижу:

for (county, countryName, stateTuple) in MyTuple:
     for (state, stateName, CountyTuple) in stateTuple:
         ...

и т. Д., Который является повторяющимся шаблоном.

def extract( myTuple, level ):
    if level:
        return ( item[2] for item in myTuple if len(item) == 3)
    else:
        return ( (item[0], item[1]) for item in myTuple )

Затем вызывайте extract столько раз, сколько вам нужно для вашей "глубины".

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...