【问题标题】:Counter not working in CSV reading script计数器在 CSV 读取脚本中不起作用
【发布时间】:2018-03-11 12:47:32
【问题描述】:

这是我在 Stackoverflow 上的第一个 Python 脚本/问题/步入真正的编码。

我希望计算某些字符串出现在我正在迭代的行中的次数,然后打印出这些值。我没有设置分隔符,所以只有一列。本质上我是说,如果列包含所述字符串,则添加到计数器。

问题是,我的所有变量的输出都为 0。有什么建议吗?

这里是代码(抱歉太长了)。

# read the CSV file

import csv
with open('example.csv', 'r') as csvfile:

reader = csv.reader(csvfile)

# set up counter variables
googlebot = 0
googlebot_mobile = 0
apis_google = 0
adsense = 0
adsbot_mobile_web_android = 0
adsbot_mobile_web = 0
adsbot = 0
googlebot_images = 0
googlebot_news = 0
googlebot_video = 0
mobile_adsense = 0
mobile_apps_android = 0

# set up counter identifiers
googlebot_string = 'Mozilla/5.0 (Linux; Android 6.0.1; Nexus 5X Build/MMB29P) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.96 Mobile Safari/537.36 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)'
googlebot_mobile_string = 'Mozilla/5.0 (Linux; Android 6.0.1; Nexus 5X Build/MMB29P) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.96 Mobile Safari/537.36 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)'
apis_google_string = 'APIs-Google (+https://developers.google.com/webmasters/APIs-Google.html)'
adsense_string = 'Mediapartners-Google'
adsbot_mobile_web_android_string = 'Mozilla/5.0 (Linux; Android 5.0; SM-G920A) AppleWebKit (KHTML, like Gecko) Chrome Mobile Safari (compatible; AdsBot-Google-Mobile; +http://www.google.com/mobile/adsbot.html)'
adbot_mobile_web_string = 'Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1 (compatible; AdsBot-Google-Mobile; +http://www.google.com/mobile/adsbot.html)'
adsbot_string = 'AdsBot-Google (+http://www.google.com/adsbot.html)'
googlebot_images_string = 'Googlebot-Image/1.0'
googlebot_news_string = 'Googlebot-News'
googlebot_video_string = 'Googlebot-Video/1.0'
mobile_adsense_string = 'compatible; Mediapartners-Google/2.1; +http://www.google.com/bot.html'
mobile_apps_android_string = 'AdsBot-Google-Mobile-Apps'

# iterate and search for/add to counter
for row in reader:
    if googlebot_string in row:
        googlebot += 1

    elif googlebot_mobile_string in row:
        googlebot_mobile += 1

    elif apis_google_string in row:
        apis_google += 1

    elif adsense_string in row:
        adsense += 1

    elif adsbot_mobile_web_android_string in row:
        adsbot_mobile_web_android += 1

    elif adbot_mobile_web_string in row:
        adsbot_mobile_web += 1

    elif adsbot_string in row:
        adsbot += 1

    elif googlebot_images_string in row:
        googlebot_images += 1

    elif googlebot_news_string in row:
        googlebot_news += 1

    elif googlebot_video_string in row:
        googlebot_video += 1

    elif mobile_adsense_string in row:
        mobile_adsense += 1

    elif mobile_apps_android_string in row:
        mobile_apps_android += 1



# print counts
print "Googlebot (Desktop): ", googlebot
print "Googlebot (Mobile): ", googlebot_mobile
print "APIs Google: ", apis_google
print "AdSense: ", adsense
print "AdsBot Mobile Web Android: ", adsbot_mobile_web_android
print "AdsBot Mobile Web: ", adsbot_mobile_web
print "AdsBot: ", adsbot
print "Googlebot Images: ", googlebot_images
print "Googlebot News: ", googlebot_news
print "Googlebot Video: ", googlebot_video
print "Mobile AdSense: ", mobile_adsense
print "Mobile Apps Android: ", mobile_apps_android

【问题讨论】:

  • 看起来那里有很多重复,else-if-control 流程似乎没有任何意义,因为它在每个字符串中最多增加一个计数器。您是否考虑过使用数组而不是一千个单独的变量?
  • 这种东西有一个方便的字典子类,名为collections.Counter
  • @AndreyTyukin 你能详细说明一下它是如何没有意义的吗?一行中只会出现我创建的变量之一(由#counter 标识符下的字符串表示)。因此,我只希望其中一个在每一行中增加。您能否澄清一下 elif googlebot_mobile_string in row 的语法是否正确。我将研究数组以使内容更易于阅读。
  • @Matt 啊,好的...如果您希望每行最多一个关键字,那么elif 是正确的,甚至比每次检查每个关键字更有效。如果每行有多个关键字,它将无法按预期工作,但显然这不是必需的。尽管如此,还是有很多重复。

标签: python loops counter


【解决方案1】:

您正在with 上下文管理器之外读取文件。 你的代码应该是:

with open('example.csv', 'r') as csvfile:
    reader = csv.reader(csvfile)

否则,您甚至在阅读文件之前就已经打开和关闭了它。

编辑:

正如@yann-vernier 所指出的,reader 必须在 with 块内使用。也就是说,for 循环应该全部缩进。

【讨论】:

  • 抱歉,我复制粘贴的代码肯定翻译不正确。我的代码和你的一模一样。
  • 这还不够。 reader 必须使用 with 块内的文件内容。
【解决方案2】:

我没有设置分隔符所以只有一列

如果不指定分隔符,则使用默认分隔符,即逗号,。所以,仍然可能有多个列,因此列表中的多个元素row

现在,googlebot_string 中的字符串也包含逗号,因此,如果此字符串存在于您的输入 CSV 中,则它永远不会作为单个元素出现在 row 中。因此googlebot_string in row 总是false。其他一些*_string 字符串也有同样的问题。

您可以将文件作为文本文件打开(不使用csv 模块)并遍历行。

一个肮脏的解决方案是指定一个输入文件中不存在的字符作为csv.reader 的分隔符。

【讨论】:

  • 这解决了我的问题,谢谢!我最终使用 " 作为分隔符并且它起作用了。
  • 酷,我已接受并投票(投票不会显示,因为我的代表少于 15 个)
猜你喜欢
  • 2023-03-18
  • 1970-01-01
  • 2020-07-15
  • 2014-04-17
  • 2014-11-17
  • 1970-01-01
  • 1970-01-01
  • 2020-06-26
  • 2021-10-26
相关资源
最近更新 更多