有没有一种方法可以同时评估两个案例,在python中使用大于和小于



我正在尝试对一个包含21列和大量行的数据集进行分类。我已经到了可以将数据导入csv并打印出单独列的地步。我还有两件事要做。首先,我希望能够打印出特定的数据点。例如,位于第2行第4列中的数据点。第二个任务是根据第4列和第5列对数据行进行分类。这些列是纬度和经度。我正试图获得世界某个特定地区的争吵。所以我的想法是这个

if  60 > row[4] > 45 and 165 > row[1] > 150:

ie(就像数学运算(9>x>5))

我不确定做上述程序的正确方法是什么。

我已将代码粘贴到底部。我是python编程的新手,所以可以随意指出错误。

import csv
path = r'C:Documents and Settingseag29278My Documentspython test codetest_satdata.csv'
with open(path, 'rb') as f:
    reader = csv.reader(f, delimiter=',')
    for row in reader:
        print row [0]
        #this prints out the first column 
    var1 = []
    for row in f:
       if  60 > row[4] > 45 and 165 > row[1] > 150:
          var1.append(row)
print var1

更新1

好吧,所以我更新了代码,但当我运行模块时,我得到了这个输出。。

2010年2010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010[]

所以我看到程序打印出var1,但它是空的

来自文档:

比较可以任意链接,例如,x < y <= z是等价的对于x < yy <= z,除了y仅被评估一次(但在两者中当发现CCD_ 6为假时,情况CCD_。

所有关于"链式比较"(例如60 > foo > 45)的答案都完全没有切中要害。你对链式比较没有问题。但是您的代码中有很多问题。

首先,CSV读取器返回的行总是将字符串作为元素。所以如果CSV看起来像

10,20,abc,40

当你使用CSV阅读器时,它在Python中变成了

['10', '20', 'abc', '40']  # list of strings

在Python 2中,将字符串与数字进行比较"有效",因为您可以这样做,而且不会引发任何异常。但这通常不是你想要的。例如:

Python 2.7.3 (default, Apr 10 2012, 23:24:47) [MSC v.1500 64 bit (AMD64)] on win
32
Type "help", "copyright", "credits" or "license" for more information.
>>> 1 < '2'
True
>>> 2 < '1'
True

请注意,Python3甚至不允许您将字符串与数字进行比较:

Python 3.2.3 (default, Apr 11 2012, 07:12:16) [MSC v.1500 64 bit (AMD64)] on win
32
Type "help", "copyright", "credits" or "license" for more information.
>>> 1 < '2'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unorderable types: int() < str()
>>>

因此,您需要做的一件事是将CSV中的字符串转换为整数:

>>> 1 < '2' < 3  # Python 2
False
>>> 1 < int('2') < 3
True

您需要做的另一件事是确保您正在读取CSV行,而不是文件中的普通老行。在哪里

var1 = []
for row in f:
   if  60 > row[4] > 45 and 165 > row[1] > 150:
      var1.append(row)

您正在做的是将每行的第5个字符与60和45进行比较,将每行第2个字符串分别与165和150进行比较。你几乎可以肯定是指

var1 = []
for row in reader:
    if 60 > int(row[4]) > 45 and 165 > int(row[1]) > 150:
        var1.append(row)

但不幸的是,这还不是全部。在进行时,您已经"用完"了CSV中的所有行

for row in reader:
    print row [0]

在该循环结束时,reader没有更多的行可供读取。最简单的方法是重新打开文件,并为每个循环使用一个新的读取器:

with open(path, 'rb') as f:
    reader = csv.reader(f, delimiter=',')  # why specify the delimiter?
    for row in reader:
        print row[0]
        #this prints out the first column 
with open(path, 'rb') as f:  # we open the file a second time
    reader = csv.reader(f)
    var1 = []
    for row in f:
        if 60 > int(row[4]) > 45 and 165 > int(row[1]) > 150:
            var1.append(row)

对于初学者,甚至是最有经验的Python程序员来说,这就足够了。代码清晰到显而易见的程度,这通常是一件好事。如果特殊情况要求采取更大胆的措施,那么看看过去的这些问题,寻找可能的替代方案:

在Python中可以重置迭代器吗?

为多次迭代重置csv.reader的正确方法?

此行:

if  60 > row[4] > 45 and 165 > row[1] > 150:

正在比较CCD_ 9。我猜这不是你想要的。for row in f为文件中的每一行生成一个字符串。我想在进行这些比较之前,你应该先做一些解析。或者您可能想要迭代reader而不是ff是文件本身,而不是csv读取器。

这应该效果更好:

with open(path, 'rb') as f:
    reader = csv.reader(f, delimiter=',')
    var1 = [] # This is a very poorly named variable, by the way.
    for row in reader:
        print row [0]
        if  60 > row[4] > 45 and 165 > row[1] > 150:
            var1.append(row)

这在Python中实际上可以很好地工作。大多数其他语言都不允许你这么做;你必须写60 > row[4] and row[4] > 45 and ...

通常使用<编写它,使其看起来更像BETWEEN操作。。。

if  (45 < row[4] < 65) and (150 < row[1] < 165):

Chaining也适用于其他运算符,例如==isin。存在一个隐含的CCD_ 20。

你可以在这里使用列表理解

var1 = [row for row in f if 45 < row[4] < 60 and 150 < row[1] < 165]

我同意@Jon的观点。使用<> 读起来更自然

最新更新