将 Python/writing 中的越界处理为 CSV
Handling out of bounds in Python/writing to CSV
我正在通过编写一些简单的程序来学习 Python。我正在尝试执行以下操作 -
我有一个 xlsx。它的格式是:
Team, Player
我想做的是对现场团队应用过滤器,然后从每个团队中随机抽取 3 名球员。
例如,我的 XLS 看起来像:
Man Utd, Ryan Giggs
Man Utd, Paul Scholes
Man Utd, Paul Ince
Man Utd, Danny Pugh
Liverpool, Steven Gerrard
Liverpool, Kenny Dalglish
...
我想最终得到一个 XLS,由每支球队的 3 名随机球员组成,在少于 3 名球员的情况下只有 1/2(这就是我正在努力解决的问题)。
我是这样开始的:
import xlrd, random, csv
# First open the workbook
wb = xlrd.open_workbook('C:\Users\ADMIN\Desktop\1.xlsx')
# Then select the sheet.
sheet = wb.sheet_by_name('Sheet1')
# Then get values of each column. Excuse first item which is header
teams = sheet.col_values(0)[1:]
players = sheet.col_values(1)[1:]
filtered_teams = filter(lambda x: x[0] > 2, zip(teams, players))
teams = {}
for t,p in zip(teams,players):
if t in teams:
teams[t].append(p)
else:
teams[t] = [p]
samples = [teams[t] + random.sample(teams[t],3) for t in teams]
myFile = open('C:\Users\ADMIN\Desktop\1.csv', 'wb')
wr = csv.writer(myFile, quoting=csv.QUOTE_ALL)
wr.writerow(samples)
我遇到的问题-
wr.writerow(samples)
TypeError: a bytes-like object is required, not 'str'
我需要在这里进行某种显式转换吗?我该如何解决这个问题?
此外,在创建示例时,如果我使用 teams/players 的所有列表:
samples = [teams[t] + random.sample(teams[t],1) for t in teams]
它会起作用,但如果我使用:
samples = [teams[t] + random.sample(teams[t],3) for t in teams]
我得到了一个越界异常,因为有些球队没有 3 名球员与之相关(只有 1 名)。确切地说,我得到:
raise ValueError("Sample larger than population or is negative")
ValueError: Sample larger than population or is negative
(我简单的 Java 大脑将其理解为 OOB)。
此时我如何解决 this/just 让它移动到下一个团队?某种 try{assignment} catch{move to next team} 机制。
有人可以提供任何 feedback/advice 吗?
谢谢!
编辑:
抛出的错误已由下面的 Jean-François Fabre 解决,非常感谢。然而,现在,当我写到 CSV 时,它只有 returns 17 行(应该有数百行),而且格式完全错误......我希望写这样的东西:
Man Utd, Ryan Giggs
Man Utd, Paul Scholes
Man Utd, Danny Pugh
Liverpool, Steven Gerrard
Liverpool, Kenny Dalglish
但似乎只有玩家返回,没有任何真正的订单?事实上,如果我将其更改为 random.sample(teams[t],min(2,len(teams[t]))
我仍然有 5/6 名球员返回每支球队...
知道我的逻辑错误在哪里吗?
好吧,这是 2 个(现在是 3 个 :))合而为一的问题。因为我已经找到了所有问题的答案,所以我会加入:
myFile = open('C:\Users\ADMIN\Desktop\1.csv', 'wb')
仅适用于 Python 2。对于 python 3,您必须以文本模式打开(并且可能必须添加 newline=""
以避免虚假行空白:
myFile = open('C:\Users\ADMIN\Desktop\1.csv', 'w', newline="")
对于您的其他问题,只需更改:
random.sample(teams[t],3)
进入
random.sample(teams[t],min(3,len(teams[t]))
所以你总是在界限之内。
现在,关于垃圾输出,您正在创建一个列表列表,但您只使用 writerow
写了一行。起初这让我感到震惊,但后来我忘记了 :) 请改用 writerows
,否则您只会得到一行表示为字符串的列表,其中包含方括号、逗号...
还有一个问题:文件中缺少球队信息,因为你只生成了球员名字。
总而言之,我会像这样重写整个内容并进行一些改进:
samples = [[team] + players + random.sample(players,min(3,len(players)) for team,players in teams.items()]
with open(r'C:\Users\ADMIN\Desktop.csv', 'w', newline='') as myFile:
wr = csv.writer(myFile, quoting=csv.QUOTE_ALL)
wr.writerows(samples)
我正在通过编写一些简单的程序来学习 Python。我正在尝试执行以下操作 -
我有一个 xlsx。它的格式是:
Team, Player
我想做的是对现场团队应用过滤器,然后从每个团队中随机抽取 3 名球员。
例如,我的 XLS 看起来像:
Man Utd, Ryan Giggs
Man Utd, Paul Scholes
Man Utd, Paul Ince
Man Utd, Danny Pugh
Liverpool, Steven Gerrard
Liverpool, Kenny Dalglish
...
我想最终得到一个 XLS,由每支球队的 3 名随机球员组成,在少于 3 名球员的情况下只有 1/2(这就是我正在努力解决的问题)。
我是这样开始的:
import xlrd, random, csv
# First open the workbook
wb = xlrd.open_workbook('C:\Users\ADMIN\Desktop\1.xlsx')
# Then select the sheet.
sheet = wb.sheet_by_name('Sheet1')
# Then get values of each column. Excuse first item which is header
teams = sheet.col_values(0)[1:]
players = sheet.col_values(1)[1:]
filtered_teams = filter(lambda x: x[0] > 2, zip(teams, players))
teams = {}
for t,p in zip(teams,players):
if t in teams:
teams[t].append(p)
else:
teams[t] = [p]
samples = [teams[t] + random.sample(teams[t],3) for t in teams]
myFile = open('C:\Users\ADMIN\Desktop\1.csv', 'wb')
wr = csv.writer(myFile, quoting=csv.QUOTE_ALL)
wr.writerow(samples)
我遇到的问题-
wr.writerow(samples)
TypeError: a bytes-like object is required, not 'str'
我需要在这里进行某种显式转换吗?我该如何解决这个问题?
此外,在创建示例时,如果我使用 teams/players 的所有列表:
samples = [teams[t] + random.sample(teams[t],1) for t in teams]
它会起作用,但如果我使用:
samples = [teams[t] + random.sample(teams[t],3) for t in teams]
我得到了一个越界异常,因为有些球队没有 3 名球员与之相关(只有 1 名)。确切地说,我得到:
raise ValueError("Sample larger than population or is negative")
ValueError: Sample larger than population or is negative
(我简单的 Java 大脑将其理解为 OOB)。
此时我如何解决 this/just 让它移动到下一个团队?某种 try{assignment} catch{move to next team} 机制。
有人可以提供任何 feedback/advice 吗?
谢谢!
编辑:
抛出的错误已由下面的 Jean-François Fabre 解决,非常感谢。然而,现在,当我写到 CSV 时,它只有 returns 17 行(应该有数百行),而且格式完全错误......我希望写这样的东西:
Man Utd, Ryan Giggs
Man Utd, Paul Scholes
Man Utd, Danny Pugh
Liverpool, Steven Gerrard
Liverpool, Kenny Dalglish
但似乎只有玩家返回,没有任何真正的订单?事实上,如果我将其更改为 random.sample(teams[t],min(2,len(teams[t]))
我仍然有 5/6 名球员返回每支球队...
知道我的逻辑错误在哪里吗?
好吧,这是 2 个(现在是 3 个 :))合而为一的问题。因为我已经找到了所有问题的答案,所以我会加入:
myFile = open('C:\Users\ADMIN\Desktop\1.csv', 'wb')
仅适用于 Python 2。对于 python 3,您必须以文本模式打开(并且可能必须添加 newline=""
以避免虚假行空白:
myFile = open('C:\Users\ADMIN\Desktop\1.csv', 'w', newline="")
对于您的其他问题,只需更改:
random.sample(teams[t],3)
进入
random.sample(teams[t],min(3,len(teams[t]))
所以你总是在界限之内。
现在,关于垃圾输出,您正在创建一个列表列表,但您只使用 writerow
写了一行。起初这让我感到震惊,但后来我忘记了 :) 请改用 writerows
,否则您只会得到一行表示为字符串的列表,其中包含方括号、逗号...
还有一个问题:文件中缺少球队信息,因为你只生成了球员名字。
总而言之,我会像这样重写整个内容并进行一些改进:
samples = [[team] + players + random.sample(players,min(3,len(players)) for team,players in teams.items()]
with open(r'C:\Users\ADMIN\Desktop.csv', 'w', newline='') as myFile:
wr = csv.writer(myFile, quoting=csv.QUOTE_ALL)
wr.writerows(samples)