Python 3:在不迭代

时间:2015-08-22 20:05:39

标签: python csv python-3.x for-loop iterator

对于项目,我需要检查csv文件,如果下一行的某列中的值等于当前行的同一列中的值。我正在使用字典csv阅读器,即阅读器中的每一行都是字典文件。我可以使用列标题作为键来访问某一行的值:row[header] = value

我当前代码的精简版本如下所示:

import csv

with open(os.path.abspath(path_to_file), "r") as f:
    reader = csv.DictReader(f, dialect='excel')

    for row in reader:
        current_row = row
        next_row = reader.__next__()
        if current_row[column] == next_row[column]:
            dosomething()

这里的问题当然是我使用__next__()跳过下一次迭代,即

(1)我进入循环; row = row1 (2)current_row = row1,next_row = row2 (3)我进入循环的下一次迭代; row = row3因为我使用了__next__()。 current_row = row3,next_row = row4

在这个例子中,我永远不会检查row2 == row3

是否可以在不迭代迭代器对象的情况下检查下一行的值? 或者,是否存在与__next__()相反的方法,这使得迭代器返回一步?

请注意:我正在将当前值与下一个进行比较,而不是当前值到 last 值,因为我不知道我正在阅读的文件有多长。我必须将文件的最后一行视为与其他文件不同,所以我必须检查reader.__next()__,看看是否有最后一行。

6 个答案:

答案 0 :(得分:4)

尝试itertools pairwise食谱。更通用的解决方案是tee你的迭代器(这是成对配方使用的)。另一种可能性是创建一个具有cur和next变量的函数,并产生你想要的值(基本上是成对的,但是你可以使它产生CSV中的字段而不是整行)。

来自https://docs.python.org/2/library/itertools.html

def pairwise(iterable):
     "s -> (s0,s1), (s1,s2), (s2, s3), ..."
    a, b = tee(iterable)
    next(b, None)
    return izip(a, b)

我认为成对会做你需要的所有事情,所以不要对你自己的生成器函数或tee进行讨论。

reader = csv.DictReader(f, dialect='excel')

for current_row, next_row in pairwise(reader):
    if current_row[column] == next_row[column]:
        dosomething()

要意识到如果你有一个带有n个项目的iterable,那么成对会有n-1个项目。

答案 1 :(得分:3)

您的要求与内置迭代器的想法相冲突。所以我建议你将自行车封装在自定义迭代器中。 想法是从原始迭代器中产生两个值,其中最后一行的下一个值为None。

答案 2 :(得分:0)

我不知道这是否可行,但它适用于android

reader = csv.DictReader(f, dialect='excel')
  reader2 = csv.DictReader(f, dialect='excel')

  for row in reader:
    current_row = row

        for row2 in reader2
          next_row = reader2.__next__()
          if current_row[column] == next_row[column]:
          dosomething()
          continue

答案 3 :(得分:0)

就个人而言,我会回顾一下,而不是向前看,假设你的场景的约束允许它:

it = iter(reader)
prev_row = it.next()
while True:
    try:
        cur_row = it.next()
        if cur_row[column] == prev_row[column]:
            dosomething()
        prev_row = cur_row
    except StopIteration:
        break

答案 4 :(得分:0)

因为字典必须保留唯一键(因此不能追加具有相同键的行)并且Drawable drawable = getResources().getDrawable(R.drawable.<your_animation_xml_file_name>) 对象不可订阅(因此无法引用列或行号),请考虑将csv数据读入列表然后将行与后续行进行比较:

package com.apps.skytek.notify;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.service.notification.NotificationListenerService;
import android.service.notification.StatusBarNotification;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;
import android.view.WindowManager;

public class NotificationService extends NotificationListenerService {





    private WindowManager windowManager;

    Context context;

    private AchievementUnlocked Notify;

    PendingIntent notifIntent;

    NotificationManager mNotificationManager;
    private StatusBarNotification sbn;


    @Override

    public void onCreate() {

        super.onCreate();
        context = getApplicationContext();
        mNotificationManager = (NotificationManager) getSystemService("notification");


    }
    public void onNotificationPosted(StatusBarNotification sbn) {


        String pack = sbn.getPackageName();
        String ticker = sbn.getNotification().tickerText.toString();
        Bundle extras = sbn.getNotification().extras;
        String title = extras.getString("android.title");
        String text = extras.getCharSequence("android.text").toString();


        Log.i("Package", pack);
        Log.i("Ticker", ticker);
        Log.i("Title", title);
        Log.i("Text", text);


        Intent msgrcv = new Intent("Msg");
        msgrcv.putExtra("package", pack);
        msgrcv.putExtra("ticker", ticker);
        msgrcv.putExtra("title", title);
        msgrcv.putExtra("text", text);


        LocalBroadcastManager.getInstance(context).sendBroadcast(msgrcv);


        Notification notification = sbn.getNotification();
        String s = sbn.getPackageName();
        //cancelNotification(sbn.getKey());

        notifIntent = notification.contentIntent;
        try {
          notifIntent.send();
        } catch (PendingIntent.CanceledException e) {
          e.printStackTrace();
        }




    }

答案 5 :(得分:0)

def pairwise(iterable):
    "s -> (s0,s1), (s1,s2), (s2, s3), ..."
    a, b = tee(iterable)
    next(b, None)
    return izip(a, b)

(sy,None)或(sy,&#34;&#34;)将是最后一个元组的唯一逻辑可能性,因为这些值一次从一个队列中弹出直到它结束。

&#34;一旦tee()进行了拆分,原始的iteable不应该在其他任何地方使用;否则,迭代可以在没有通知tee对象的情况下进行推进。&#34;