在Python字典中截断密钥长度

时间:2014-06-03 14:25:24

标签: python dictionary truncate

我有一个Python字典,我试图插入到mysql中。问题是字典中的一个键长度超过64个字符(mysql中列的最大长度)。所以我需要将所有字典键截断为64个字符。

以下代码适用于所有方面,但长度超过64个字符的密钥除外= location_of_building_on_the_lot_if_garage_change_type_code_to_bgd _

data = {'x_coordinate': '1158020.73068669',
    'any_people_using_property_homeless_childen_gangs_': True,
    'police_district': '8',
    'location_of_building_on_the_lot_if_garage_change_type_code_to_bgd_': 'Front',
    'service_request_number': '14-00630589',
    'address_street_suffix': 'AVE',
    'y_coordinate': '1866585.99638448',
    'date_service_request_was_received': '2014-05-01T00:00:00',
    'address_street_number': '5719',
    'longitude': '-87.69612590561026',
    'latitude': '41.78965826126179',
    'address_street_name': 'FRANCISCO',
    'address_street_direction': 'S',
    'location': {'latitude': '41.78965826126179', 'needs_recoding': False, 'longitude': '-87.69612590561026'},
    'service_request_type': 'Vacant/Abandoned Building',
    'community_area': '63',
    'is_the_building_currently_vacant_or_occupied_': 'Vacant',
    'ward': '16',
    'is_building_open_or_boarded_': 'Open',
    'is_the_building_vacant_due_to_fire_': True,
    'zip_code': '60629'}


placeholders = ', '.join(['%s'] * len(data))
columns = ', '.join(data.keys())
sql = "INSERT INTO vacant_buildings (%s) VALUES (%s)" % (columns, placeholders)

我试图改变:

columns = ', '.join(data.keys())

columns = ', '.join(data[:64].keys())

但是出现以下错误:TypeError:unhashable type

思想?

3 个答案:

答案 0 :(得分:2)

你想截断键(=字符串),而不是数据(这是一个字典,没有"长度"在"字符"意义上):

columns = ', '.join(d[:64] for d in data.keys())

答案 1 :(得分:1)

Pavel的答案很好,但是如果您因为截断而担心名称空间冲突

例如,location_of_building_on_the_lot_if_garage_change_type_code_to_bgd_location_of_building_on_the_lot_if_garage_change_type_code_to_bgd_hahaha在截断它们之前会是不同的键,此时它们是相同的键。

keys = []
for k in data.keys():
    newKey = k[:64]
    count = 1
    while newKey in keys:
        alteration = str(count)
        newKey = newKey[:-len(alteration)] + alteration
        count += 1
    keys.append(newKey)

columns = ', '.join(keys)

答案 2 :(得分:0)

al .join()可以解决问题,它比做起来慢得多:

columns = ''
for key in data.keys():
    columns += key[:64] +', '
sql = "INSERT INTO vacant_buildings (%s) VALUES (%s)" % (columns[:-2], placeholders)

这是因为'.join()`将对你已经迭代过的列表执行迭代操作,如果你处理大量数据,手动完成这项工作将变得更快。

另请注意,x[:-2]在小插入上很好,但如果将VALUES捆绑在一起形成一个执行字符串,如下所示:

INSERT INTO table VALUES (1, 2, 3), (2,2,3), (3,2,3) ...

执行data[:-2]运算符会变得极其缓慢,其中一个计数器检查您是否在列表中的最后一项上会很棒,因此最后会跳过+', '

如果您要删除值,请在一个for循环而不是两个循环中执行此操作:

for key, value in data.items():
    columns += key[:64] +', '

为了符合要求,未来的Python版本也会切换到执行.format()的{​​{1}},因为这已经过时了。

'something (%s) something else'

TL; DR:

手动构建字符串,而不是使用多个迭代函数,从而产生相同的结果。并使用>>> a = [1, 2, 'test'] >>> '{} is {} with {}'.format(*a) '1 is 2 with test' !!