1

以下に示すように、タプルのリストとタプルから辞書を作成しようとしています。タプルをリストに逆マップし、None 以外の列名のセットを作成する必要があります。

解決策(目的の辞書)を達成するためのpythonicな方法に関する提案は大歓迎です。

MySQL テーブル 'StateLog':

Name NY   TX   NJ
Amy  1    None 1
Kat  None 1    1
Leo  None None 1

Python コード:

## Fetching data from MySQL table
#cursor.execute("select * from statelog")
#mydataset = cursor.fetchall()
## Fetching column names for mapping
#state_cols = [fieldname[0] for fieldname in cursor.description]

state_cols = ['Name', 'NY', 'TX', 'NJ']
mydataset = (('Amy', '1', None, '1'), ('Kat', None, '1', '1'), ('Leo', None, None, '1'))

temp = [zip(state_cols, each) for each in mydataset]

# Looks like I can't do a tuple comprehension for the following snippet : finallist = ((eachone[1], eachone[0]) for each in temp for eachone in each if eachone[1] if eachone[0] == 'Name')
for each in temp:
    for eachone in each:
        if eachone[1]:
            if eachone[0] == 'Name':
                k = eachone[1]
            print k, eachone[0]

print '''How do I get a dictionary in this format'''            
print '''name_state = {"Amy": set(["NY", "NJ"]),
                "Kat": set(["TX", "NJ"]),
                "Leo": set(["NJ"])}'''

これまでの出力:

Amy Name
Amy NY
Amy NJ
Kat Name
Kat TX
Kat NJ
Leo Name
Leo NJ

必要な辞書:

name_state = {"Amy": set(["NY", "NJ"]),
              "Kat": set(["TX", "NJ"]),
              "Leo": set(["NJ"])}
4

3 に答える 3

1

defaultdictの別の仕事のように見えます!

それでは、デフォルトのdictを作成しましょう

name_state = collections.defaultdict(set)

すべてのデフォルト値としてセットを持つ辞書ができたので、次のようなことができます

name_state['Amy'].add('NY')

次に進むには、オブジェクトを繰り返し処理し、それぞれの名前に正しい状態を追加するだけです。楽しみ

于 2012-06-01T15:50:08.653 に答える
1

これを辞書内包表記として行うことができます (Python 2.7+):

from itertools import compress
name_state = {data[0]: set(compress(state_cols[1:], data[1:])) for data in mydataset}  

またはジェネレータ式として:

name_state = dict((data[0], set(compress(state_cols[1:], data[1:]))) for data in mydataset)
于 2012-06-01T15:50:41.377 に答える
1

正直に言うと、あなたの問題は、コードが煩雑になりすぎていることだと思います。「ワンライニング」の誘惑に抵抗し、関数を作成します。すべてがずっと簡単になります!

mydataset = (
        ('Amy', '1', None, '1'),
        ('Kat', None, '1', '1'),
        ('Leo', None, None, '1')
)

def states(cols, data):
    """
    This function receives one of the tuples with data and returns a pair
    where the first element is the name from the tuple, and the second
    element is a set with all matched states. Well, at least *I* think
    it is more readable :)
    """
    name = data[0]
    states = set(state for state, value in zip(cols, data) if value == '1')
    return name, states

pairs = (states(state_cols, data) for data in mydataset)
# Since dicts can receive an iterator which yields pairs where the first one
# will become a key and the second one will become the value, I just pass
# a list with all pairs to the dict constructor.
print dict(pairs)

結果は次のとおりです。

{'Amy': set(['NY', 'NJ']), 'Leo': set(['NJ']), 'Kat': set(['NJ', 'TX'])}
于 2012-06-01T15:51:02.007 に答える