将字典的值转换为小写

时间:2018-06-13 02:09:24

标签: python

我在python中有一个字典,里面有一个字典,一些值放在一个数组或列表中。

我想打印字典全部小写而不更改任何其他内容,但我只有一个普通字典的值迭代的唯一代码,它不处理数组或列表。有关如何解决此问题的任何建议?这是我到目前为止的代码:

new_data = {}
for i in range (0, len(json_file)):
    try: 
        data = json_file[i]['payload']
        for key, value in data.iteritems():
            new_data[value.lower()] = value
            print (new_data)
    except:
        continue

这是嵌套词典:

{
  "payload": {
    "existence_full": 1,
    "geo_virtual": "[\"56.9459720|-2.1971226|20|within_50m|4\"]",
    "latitude": "56.945972",
    "locality": "Stonehaven",
    "_records_touched": "{\"crawl\":8,\"lssi\":0,\"polygon_centroid\":0,\"geocoder\":0,\"user_submission\":0,\"tdc\":0,\"gov\":0}",
    "address": "The Lodge, Dunottar",
    "email": "dunnottarcastle@btconnect.com",
    "existence_ml": 0.56942382176587,
    "domain_aggregate": "",
    "name": "Dunnottar Castle",
    "search_tags": [
      "Dunnottar Castle Aberdeenshire",
      "Dunotter Castle"
    ],
    "admin_region": "Scotland",
    "existence": 1,
    "category_labels": [
      [
        "Landmarks",
        "Buildings and Structures"
      ]
    ],
    "post_town": "Stonehaven",
    "region": "Kincardineshire",
    "review_count": "719",
    "geocode_level": "within_50m",
    "tel": "01569 762173",
    "placerank": 65,
    "longitude": "-2.197123",
    "placerank_ml": 37.279160734645,
    "fax": "01330 860325",
    "category_ids_text_search": "",
    "website": "http:\/\/www.dunnottarcastle.co.uk",
    "status": "1",
    "geocode_confidence": "20",
    "postcode": "AB39 2TL",
    "category_ids": [
      108
    ],
    "country": "gb",
    "_geocode_quality": "4"
  },
  "uuid": "3867aaf3-12ab-434f-b12b-5d627b3359c3"
}

1 个答案:

答案 0 :(得分:1)

Nick A在评论中指出了一个有趣的捷径:你的dict看起来像是JSON兼容的。如果是这样,我们可以转换为JSON,小写该字符串,然后转换回来吗?有许多略有不同的JSON标准:json.orgECMA 404和RFC 4627715871598259。然后就是实际使用JSON的方式。以及它由Python的json模块实现的方式。但我会在这里总结一下:

lowered = json.loads(json.dumps(d, ensure_ascii=False).lower())

...只要工作:

  • 您的值均为dictliststrfloatintbool和{{1}类型}。
  • 您的NoneType值只有dict个键。
  • 您的strlist值不是循环的(例如dict)。
  • 您的lst = []; lst.append(lst)值绝不会包含floatmath.inf
  • 你正在使用最近的Python(3.6很好),或者永远不会有像math.nan那样的非BMP字母。
  • 你正在使用最近的Python(3.6很好),或者之外永远不会有int个值。

注意range(-(2**53)+1, (2**53))。如果你有任何非ASCII字母,这是必要的,因为ensure_ascii=False'É'.lower(),但'é'什么都不做。

对于您通过电汇或文件收到的JSON,而不是使用r'\u00c9'.lower()自行创建,当然您不能信任字符串不被转义。但您可以先dumps,然后再将loads改为小写,再dumps。 (对于这种情况,您可能希望添加loads以尽早捕获allow_nan=Falseinf值,以便更容易调试。)

使用第三方库simplejson(stdlib nan所基于的)可能会消除对最近Python的要求,并可能为其他一些可能的问题提供解决方法,但我没有'试了一下。

如果无论出于何种原因这种黑客行为是不可接受的,那么更干净的方法是通过结构进行递归。一个简单的版本看起来像这样:

json

当然,您不使用JSON的原因可能是您的类型并非都直接映射到JSON,这意味着它们可能无法使用上述内容。但您可以根据需要轻松扩展它。例如:

要处理非字符串键,请替换def recursive_lower(obj): if isinstance(obj, str): return obj.lower() elif isinstance(obj, list): return [recursive_lower(elem) for elem in obj] elif isinstance(obj, dict): return {key.lower(): recursive_lower(value) for key, value in obj.items()} else: return obj 子句:

dict

要处理 elif isinstance(obj, dict): return {recursive_lower(key): recursive_lower(value) for key, value in obj.items()} 和其他非tuple的序列,请替换list子句(确保在list检查后出现,因为{{ 1}}是str类型...):

str

要处理Sequence(作为纯ASCII字符串),请更改 elif isinstance(obj, collections.abc.Sequence): return type(obj)(map(recursive_lower, obj)) 部分:

bytes

要使用str方法( if isinstance(obj, (str, bytes)): return obj.lower() lowerstr,各种第三方类型对任何内容进行欺骗,请更改bytes部分:

bytearray

等等。