【问题标题】:Can't merge two dictionaries into one dictionary无法将两个字典合并为一个字典
【发布时间】:2021-03-13 17:11:42
【问题描述】:

所以我遇到了无法将两个字典合并到一个字典中的问题。这是我的代码:

def create_app():
    app = Flask(__name__)

    @app.route('/', methods=['POST'])
    def index():
        news_site = request.get_json()
        print(news_site)

        scrapdata = {}
        scrapdata2 = {}

        if news_site.get('kompas', True) and news_site.get('detik', True) == True:
            scrapdata = kompas_fun()
            scrapdata2 = detik_fun()
            fscrapdata = {**scrapdata, **scrapdata2}
            return jsonify(fscrapdata)

        elif news_site.get('kompas', True) == False:
            scrapdata = detik_fun()
            fscrapdata = {**scrapdata}
            return jsonify(fscrapdata)

        elif news_site.get('detik', True) == False:
            scrapdata = kompas_fun()
            fscrapdata = {**scrapdata}
            return jsonify(fscrapdata)

        else:
            return jsonify({'value': 'error'})

    return app

当输入与if 条件匹配时,它只返回scrapdata2 字典,而不是合并scrapdatascrapdata2。所以结果就是scrapdata2字典

我已经尝试了How do I merge two dictionaries in a single expression in Python (taking union of dictionaries)? 的解决方案,但仍然无法正常工作。或者使用reduceupdateChainMap,但还是不行。

编辑:对于输入,我使用的是使用 json 的 Postman,这是输入:

{
    "kompas":true,
    "detik":true
}

这是我上面代码的输出,但我只从输出的许多字典中发布了几个:

{
    "data": [
        {
            "author": "Sachril Agustin Berutu",
            "category": "detikNews",
            "content": "Beredar dokumen hasil tes swab Habib Rizieq Shihab (HRS) positif Corona. Wali Kota Bogor Bima Arya mengaku tidak mengetahui apakah dokumen tes swab Habib Rizieq itu asli atau palsu., \"Kita tidak bisa pastikan itu asli apa palsu,\" kata Bima saat dihubungi, Rabu (2/12/2020)., \n",
            "date": "02 Des 2020",
            "headline": "\nDialog 212 Dimulai, Habib Rizieq Hadir di Lokasi Terpisah\n",
            "link": "https://news.detik.com/berita/d-5277968/dialog-212-dimulai-habib-rizieq-hadir-di-lokasi-terpisah",
            "tag": "habib rizieq",
            "time": "09:58 WIB",
            "total comment": "240"
        },
        {
            "author": "Achmad Dwi Afriyadi",
            "category": "detikFinance",
            "content": "Industri hulu migas merupakan industri yang penuh ketidakpastian. Untuk menarik investasi, pemerintah berupaya mengurangi ketidakpastian tersebut., Menteri ESDM Arifin Tasrif mengatakan, ketidakpastian sendiri berasal eksternal dan internal.",
            "date": "02 Des 2020",
            "headline": "\nCara Pemerintah 'Manjakan' Investor Migas\n",
            "link": "https://finance.detik.com/energi/d-5278096/cara-pemerintah-manjakan-investor-migas",
            "tag": "migas",
            "time": "11:18 WIB",
            "total comment": "0"
        }
    ],
    "news_portal": "detik"
}

kompas_fun()detik_fun() 从两个新闻网站的网络抓取中返回字典。但仅来自detik_fun() 的输出。 kompas_fun() 有效并返回一个列表,但未与来自 detik_fun 的结果合并。

这是从kompas_fun()结束的,它将结果附加并转换为字典:

      arti.append({
        'headline': title,
        'content':content,
        'writer': writer,
        'editor': editor,
        'category' : cat,
        'tag' : tag1,
        'total comment': comment,
        'date': dates,
        'time': times,
        'read count': rcount,
        'link': lnk
        
      })
  df = pd.DataFrame(arti)
  list_dct = df.to_dict(orient='records')
  dct = {"date": scrapdate, 'news_portal': 'kompas', "data": list_dct}
  return dct

来自detik_fun() 与上面相同。不同的只是 `'news_portal': 'detik'。

任何帮助将不胜感激。

【问题讨论】:

  • 你能展示一个输入和输出的例子吗?
  • kompas_fun()的回复是什么?
  • 试试这个fscrapdata = {k:v for k, v in scrapdata.items()+scrapdata2.items()}
  • scrapdatascrapdata2 有相同的键吗?
  • @neilharia7 编辑了我的帖子

标签: python


【解决方案1】:

由于我们在这里只关心合并两个字典,所以我们限制对这个代码块的讨论。

if news_site.get('kompas', True) and news_site.get('detik', True) == True:
    scrapdata = kompas_fun()
    scrapdata2 = detik_fun()
    fscrapdata = {**scrapdata, **scrapdata2}
    return jsonify(fscrapdata)

fscrapdata = {**scrapdata, **scrapdata2} 不起作用,因为scrapdata2 替换了scrapdata 中的数据。下面的代码说明了这是如何发生的。

print({**{"data":[1,2,3]}, **{"data":[4,5,6]}})

输出:

{'data': [4, 5, 6]}

两个字典都以“数据”为键,因此后者将替换前者的值。

您不能将具有相同名称但具有不同值的两个键放在字典中。但是您可以将字典存储为列表中的项目或另一个字典中的值。

# Make a new list containing both of them
scrapdata = kompas_fun()
scrapdata2 = detik_fun()
fscrapdata = [scrapdata, scrapdata2]
# Make a new dictionary containing and assign each of them a unique key.
scrapdata = kompas_fun()
scrapdata2 = detik_fun()
fscrapdata = {"1":scrapdata, "2":scrapdata2}

但是,如果这不是您要查找的内容,您也可以考虑为每个键附加元素。

scrapdata = kompas_fun()
scrapdata2 = detik_fun()
fscrapdata = {}
for k, v in list(scrapdata1.items()) + list(scrapdata2.items()):
    # Create a new list if the current key doesn't have a list yet. Do no change otherwise.
    fscrapdata[k] = fscrapdata[k] if k in fscrapdata else []
    fscrapdata[k].append(v)

这将产生如下结果:

{'data': [[{'author': 'Sachril Agustin Berutu',
            'category': 'detikNews',
            ......
            'total comment': '240'},
           {'author': 'Achmad Dwi Afriyadi',
            'category': 'detikFinance',
            ......
            'total comment': '0'}],
          [{'author': 'Sachril Agustin Berutu',
            'category': 'kompasNews',
            ......
            'total comment': '240'},
           {'author': 'Achmad Dwi Afriyadi',
            'category': 'kompasFinance',
            ......
            'total comment': '0'}]],
 'news_portal': ['detik', 'kompas']}

【讨论】:

    【解决方案2】:

    对于任何可能像我一样遇到同样问题的人,最后我使用update 并使kompas_fun()detik_fun() 中的值键各自不同。

    def create_app():
        app = Flask(__name__)
    
        @app.route('/', methods=['POST'])
        def index():
            news_site = request.get_json()
            print(news_site)
    
            scrapdata = {}
            scrapdata2 = {}
    
            if news_site.get('kompas', True) and news_site.get('detik', True) == True:
                scrapdata = kompas_fun()
                scrapdata2 = detik_fun()
                for d in (scrapdata, scrapdata2): fscrapdata.update(d)
                return jsonify(fscrapdata)
    
            elif news_site.get('kompas', True) == False:
                scrapdata = detik_fun()
                fscrapdata = {**scrapdata}
                return jsonify(fscrapdata)
    
            elif news_site.get('detik', True) == False:
                scrapdata = kompas_fun()
                fscrapdata = {**scrapdata}
                return jsonify(fscrapdata)
    
            else:
                return jsonify({'value': 'error'})
    
        return app
    

    第一次知道为什么使用这种方法不起作用,我 100% 确定在运行之前已经在我的代码上保存了编辑。这并不是 100% 解决了我的问题,因为我想要的是来自 kompas_fun()detik_fun() 的结果都具有相同的密钥,并且与我上面的帖子一样与相同的 json 格式合并。

    非常感谢@PIG208 解决方案,但我必须使用与我的帖子中相同的 json 格式作为输出。

    【讨论】:

      【解决方案3】:

      使用 .update 方法():

      这是一个例子:

      d1 = {1:1, 2:2}
      d2 = {3:3, 4:4}
      
      d1.update(d2)
      
      print(d1)
      

      输出是:

      {1: 1, 2: 2, 3: 3, 4: 4}
      

      【讨论】:

      • 已经在我的帖子中说我已经在使用update 但无法正常工作
      • 我认为 update 在这里不起作用,因为它会替换冲突键的值。
      猜你喜欢
      • 2017-07-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-04
      • 2017-06-23
      • 2019-05-16
      相关资源
      最近更新 更多