Как объединить строки из словаря, идентифицируя последний элемент с помощью Python? - PullRequest
2 голосов
/ 12 июля 2010

Мне нужно объединить строку в существующую следующим образом.

for k,v in r.iteritems():
    tableGenString += "%s %s, " % (k, what_type(v))

Проблема в том, что для последнего элемента не следует добавлять запятую (',').

Как я могу проверить, является ли k, v последним элементом?

Добавлена ​​

Пример представляет собой упрощенную версию реального кода следующим образом.

for k,v in r.iteritems():
    filteredKey = m.mapper(k)
    (typestring, valuestring) = what_type(v)
    tableGenString += "%s %s, " % (k, typestring)
    string1 += "%s, " % k
    string2 += "%s, " % valuestring

Мне нужно проверить последний пункт для этого случая.

Ответы [ 4 ]

15 голосов
/ 12 июля 2010

Не создавайте больших строк с такой конкатенацией. Сделайте это вместо:

tableGenString = ', '.join('%s %s' % (k, what_type(v)) for k, v in r.iteritems())
2 голосов
/ 12 июля 2010

ОП настаивает на комментарии:

Мне нужно найти способ найти последний элемент, как я добавил к исходному вопросу

, очевидно, для других целейчем неуклюже дублирует ', '.join, правильно предложенный в других ответах.

Конечно, порядок, в котором ключи и значения представлены iteritems (или любым другим способом итерации по dict, который является хешемтаблица и не имеет понятия «порядок», а значит, не «первый» или «последний»!) совершенно произвольно.Тем не менее, последний (который должен быть представлен в этом произвольном порядке) может быть идентифицирован :

for i, (k,v) in enumerate(r.iteritems()):
    if i == len(r) - 1:
        print "last item: key=%r, value=%r" % (k, v)

Аналогично, как только вы получите i от этого вида вызова enumerate,if i==0: идентифицирует первый элемент, if i==len(r)//2: идентифицирует средний элемент и т. Д.

1 голос
/ 12 июля 2010

Используйте строковый метод join вместо outter для:

tableGenString = ", ".join ("%s %s" %(k, what_type(v) for k, v in r.iteritems())
0 голосов
/ 12 июля 2010

Тьфу. Если вам нужно что-то, что читаемо вместо чрезмерно плотного соединения, здесь:

def build_str(r):
    tableGenString = ""
    for k,v in r.iteritems():
        if tableGenString != "":
            tableGenString += ", "
        tableGenString += "%s %s" % (k, type(v))

    return tableGenString

Пример возвращаемого значения:

baz <type 'str'>, have a list <type 'list'>, foo <type 'int'>, bar <type 'str'>, or a tuple <type 'tuple'>

И чтобы кто-то не жаловался, что это как-то медленнее, чем объединение ... это не на моей коробке:

import timeit

r = {
    "foo": 123,
    "bar": "456",
    "baz": "abcd",
    "have a list": [7, 8, "efgh"],
    "or a tuple": (9, 0, 10),
}

def build_str(r):
    tableGenString = ""
    for k,v in r.iteritems():
        if tableGenString != "":
            tableGenString += ", "
        tableGenString += "%s %s" % (k, type(v))

    return tableGenString

if __name__ == '__main__':
    readable_time = timeit.Timer("build_str(r)", "from __main__ import build_str, r").timeit()
    print "Readable time: %f" % (readable_time,)

    join_time = timeit.Timer("', '.join('%s %s' % (k, type(v)) for k, v in r.iteritems())", "from __main__ import r").timeit()
    print "Join time: %f" % (join_time,)

...

$ python concat.py 
Readable time: 4.705579
Join time: 5.277732
$ 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...