【问题标题】:Output from function to text/CSV file?从函数输出到文本/CSV 文件?
【发布时间】:2016-01-06 05:29:42
【问题描述】:

我正在计算某组总统演讲中的收缩次数,并希望将这些收缩输出到 CSV 或文本文件中。这是我的代码:

import urllib2,sys,os,csv
from bs4 import BeautifulSoup,NavigableString
from string import punctuation as p
from multiprocessing import Pool
import re, nltk
import requests
import math, functools
import summarize
reload(sys)

def processURL_short(l):
    open_url = urllib2.urlopen(l).read()
    item_soup = BeautifulSoup(open_url)
    item_div = item_soup.find('div',{'id':'transcript'},{'class':'displaytext'})
    item_str = item_div.text.lower()
    return item_str

every_link_test = ['http://www.millercenter.org/president/obama/speeches/speech-4427',
'http://www.millercenter.org/president/obama/speeches/speech-4424',
'http://www.millercenter.org/president/obama/speeches/speech-4453',
'http://www.millercenter.org/president/obama/speeches/speech-4612',
'http://www.millercenter.org/president/obama/speeches/speech-5502']

data = {}
count = 0
for l in every_link_test:
    content_1 = processURL_short(l)
    for word in content_1.split():
        word = word.strip(p)
        if word in contractions:
            count = count + 1
        splitlink = l.split("/")
        president = splitlink[4]
        speech_num = splitlink[-1]
        filename = "{0}_{1}".format(president,speech_num)
    data[filename] = count
    print count, filename

   with open('contraction_counts.csv','w',newline='') as fp:
        a = csv.writer(fp,delimiter = ',')
        a.writerows(data)

运行 for 循环打印出来

79 obama_speech-4427 101 obama_speech-4424 101 obama_speech-4453 182 obama_speech-4612 224 obama_speech-5502

我想将其导出到一个文本文件,其中左侧的数字是一列,总统/演讲编号在第二列。我的with 语句只是将每一行写入一个单独的文件,这绝对不是最佳的。

【问题讨论】:

  • 如果你用谷歌搜索write csv with python,你会得到很多答案,try this one
  • 是的,我已经看到了。 CSV 的输出基本上在每列中放置一个字母,甚至不包括收缩计数。
  • 我建议编辑这个问题或创建一个关于您尝试用于输出 CSV 的代码的新问题 - 我们帮助您处理您已经尝试过的代码比我们更简单从头开始给你写点东西。
  • 我试过的代码在上面代码的尾部。它以with open('contraction_counts.csv'... 开头

标签: python csv for-loop beautifulsoup output


【解决方案1】:

你可以试试这样的,这是一个通用的方法,你觉得合适就修改

import csv
with open('somepath/file.txt', 'wb+') as outfile:
  w = csv.writer(outfile)
  w.writerow(['header1', 'header2'])
  for i in you_data_structure: # eg list or dictionary i'm assuming a list structure
    w.writerow([
      i[0],
      i[1],
    ])

如果是字典

import csv
with open('somepath/file.txt', 'wb+') as outfile:
  w = csv.writer(outfile)
  w.writerow(['header1', 'header2'])
  for k, v in your_dictionary.items(): # eg list or dictionary i'm assuming a list structure
    w.writerow([
      k,
      v,
    ])

【讨论】:

  • 我仍然将filename 的每个字母输出到“contraction_counts.csv”中的各个列...我正在尝试为counts 获取一列,为filename 获取另一列。
  • 那你就得相应地修改你的数据结构了,这个sn-p告诉你怎么做,怎么用就看你自己了。如果我有一个列表列表,例如 [[hi, hello], [by, bye]],则此代码将遍历该列表,并且 I[0] 在第一遍时为 hi,在第二遍时为 by。跨度>
  • 好的。它实际上被保存为字典(例如{'washington_speech-3446': 8873,'washington_speech-3447': 8874, ...},所以稍作修改,我想我应该会很好。
  • 好的,添加了一个如何使用字典的示例。
  • 好的。现在这绝对是有道理的,我能够阅读从字典中编写的代码。谢谢!
【解决方案2】:

您的问题是您以w 模式打开循环内的输出文件,这意味着它在每次迭代时都会被擦除。您可以通过两种方式轻松解决:

  1. open 置于循环之外(正常方式)。您将只打开一次文件,在每次迭代中添加一行并在退出 with 块时关闭它:

    with open('contraction_counts.csv','w',newline='') as fp:
        a = csv.writer(fp,delimiter = ',')
        for l in every_link_test:
            content_1 = processURL_short(l)
            for word in content_1.split():
                word = word.strip(p)
                if word in contractions:
                    count = count + 1
                splitlink = l.split("/")
                president = splitlink[4]
                speech_num = splitlink[-1]
                filename = "{0}_{1}".format(president,speech_num)
            data[filename] = count
            print count, filename
            a.writerows(data)
    
  2. a(追加)模式打开文件。在每次迭代中,您重新打开文件并在最后写入而不是擦除它 - 由于打开/关闭,这种方式会使用更多的 IO 资源,并且只有在程序可以中断并且您想确保所有这些情况下才应该使用在崩溃之前写入已实际保存到磁盘

    for l in every_link_test:
        content_1 = processURL_short(l)
        for word in content_1.split():
            word = word.strip(p)
            if word in contractions:
                count = count + 1
            splitlink = l.split("/")
            president = splitlink[4]
            speech_num = splitlink[-1]
            filename = "{0}_{1}".format(president,speech_num)
        data[filename] = count
        print count, filename
    
        with open('contraction_counts.csv','a',newline='') as fp:
            a = csv.writer(fp,delimiter = ',')
            a.writerows(data)
    

【讨论】:

  • 这两种解决方案都让我回到了我开始的地方——contraction_counts.csv 的输出是 filename 的每个字母在它自己的单独列中,没有包含实际的矛盾计数。跨度>
猜你喜欢
  • 2021-12-21
  • 2011-03-16
  • 2023-03-16
  • 1970-01-01
  • 2012-03-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多