将最新的非None值传播到izip_longest中的其余项目

时间:2013-08-14 14:33:29

标签: python

我想知道是否有办法让列表中“不匹配”项的默认值设置为izip_longtest函数中的最新值。

问题:我有一个单词,在x,y和旋转上有一个位置。这些可以是多个,并且单词的每个字母必须具有位置/旋转。

更明确地说:我有两个清单:

  • 第一个本身是一个元组(x,y,r),它们是与字母匹配的位置和旋转。
  • 第二个是与位置/旋转匹配的字符。

例如,如果我有单词“HELLO”和x = [1,2,3,4,5]y = [6,7,8,9,10]r = [11,12,13,14,15]

'H'字母将x = 1y = 6y = 11 最后一个字母“O”将包含x = 5y = 10r = 15

但是,如果单词是“问题”和x = [1],则只有'P'字母与x值匹配,而所有其他字母将设为None izip_longest

我想要的是将最新或仅x“引导”到所有其他字母。所以,如果您有任何建议或解决方案,请告诉我。谢谢提前!

4 个答案:

答案 0 :(得分:1)

正如你已经注意到的那样,package tests; import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; import java.text.DecimalFormat; import java.util.ArrayList; import java.util.List; /** * * @author Michael */ public class Tests { private String fname; private String lname; private int[] scores; public Tests(String entry) { String[] data=entry.split(" "); scores=new int[data.length-2]; this.setFname(data[0]); this.setLname(data[1]); for(int i=2;i<data.length;i++) { scores[i-2]=Integer.parseInt(data[i]); } } public int[] getScores() { return scores; } public void setScores(int[] scores) { this.scores = scores; } public static String getAverageScore(int[] a) { int sum=0; for(int e:a) { sum+=e; } return new DecimalFormat("##.##").format((double)sum/(double)a.length); } public static void showAverage(List<Tests> e) { for(Tests s:e) { System.out.println(s); } } public String getGrade() { double d=Double.parseDouble(Tests.getAverageScore(scores)); if(d<=100 && d>=90) { return "A"; } else if(d<90 && d>=80) { return "B"; } else if(d<80 && d>=70) { return "C"; } else if(d<70 && d>=60) { return "D"; } else { return "F"; } } public String getFname() { return fname; } public void setFname(String fname) { this.fname = fname; } public String getLname() { return lname; } public void setLname(String lname) { this.lname = lname; } public String toString() { return getFname()+"\t\t"+getLname()+"\t\t"+scores[0]+"\t\t"+scores[1]+"\t\t"+scores[2]+"\t\t"+scores[3]+"\t\t"+scores[4]+"\t\t"+getAverageScore(scores)+"\t\t"+getGrade(); } public static ArrayList<Tests> read(String path) { BufferedReader br = null; try { String sCurrentLine; ArrayList<Tests> ar=new ArrayList<Tests>(); br = new BufferedReader(new FileReader("C:\\Users\\Michael Jr\\Desktop\\ch9_Ex13Data.txt")); while ((sCurrentLine = br.readLine()) != null) { ar.add(new Tests(sCurrentLine)); } return ar; } catch (Exception e) { } finally { try { if (br != null)br.close(); } catch (IOException ex) { ex.printStackTrace(); } } return null; } public static void main(String[] a) { ArrayList<Tests> ar=read("E:/score.txt"); System.out.println("First_Name\tLast_Name\tTest1\t\tTest2\t\tTest3\t\tTest4\t\tTest5\t\tAverage\t\tGrade"); for(Tests e:ar) { System.out.println(e); } } } 并没有把你带到那里。但是,你可以把它包起来,并把它带到终点线。

izip_longest

def izip_longest_last_value(*args, **kwargs): last = (None,) * len(args) for x in izip_longest(*args, **kwargs): last = tuple(z if z is not None else last[y] for y,z in enumerate(x)) yield last 有* args,** kwargs的签名,所以我们在这里重复一遍。我们还支持任意数量的位置参数,因此您可以一起izip 1,2或46个不同的列表。

我们初始化最后是一个元组,只要位置args的数量。 Last将更新为包含上次迭代的值。

izip_longest是我们从包装器的内容izip_longest中获取当前值。

for x in izip_longest()我们正在更新最后一个元组,并填写izip中的当前值或者如果last = tuple(...)为该空格返回izip_longest,则填写上一个值,表明它已被填补。

答案 1 :(得分:0)

由于默认zip_longest对您不起作用,因此这是一个稍微更智能的版本:

import pprint
word = 'PROBLEM'

def zip_longest(*iterators):
    last = {}
    # Make a list of non-empty iterators
    non_empty = dict.fromkeys(range(len(iterators)))

    # Make sure it's an iterator, does no harm on iterators and helps
    # on lists
    iterators = map(iter, iterators)
    while non_empty:
        # Prepare the row
        row = []

        # Walk through the iterators in the given order
        for i, iterator in enumerate(iterators):
            # If there are still values, find the next
            if i in non_empty:
                try:
                    last[i] = iterator.next()
                except StopIteration:
                    # No items anymore, this one is empty
                    del non_empty[i]

            # Add the current (or last if it was already empty) value
            row.append(last.get(i))

        yield row

首先/简单测试:

x = [1]
y = [2]
pprint.pprint(list(zip_longest(word, x, y)))
[['P', 1, 2],
 ['R', 1, 2],
 ['O', 1, 2],
 ['B', 1, 2],
 ['L', 1, 2],
 ['E', 1, 2],
 ['M', 1, 2],
 ['M', 1, 2]]

稍微复杂一点:

x = range(3)
y = range(6)
pprint.pprint(list(zip_longest(word, x, y)))
[['P', 0, 0],
 ['R', 1, 1],
 ['O', 2, 2],
 ['B', 2, 3],
 ['L', 2, 4],
 ['E', 2, 5],
 ['M', 2, 5],
 ['M', 2, 5]]

使用其他更长的范围:

x = range(10)
y = range(5)
pprint.pprint(list(zip_longest(word, x, y)))

[['P', 0, 0],
 ['R', 1, 1],
 ['O', 2, 2],
 ['B', 3, 3],
 ['L', 4, 4],
 ['E', 5, 4],
 ['M', 6, 4],
 ['M', 7, 4],
 ['M', 8, 4],
 ['M', 9, 4],
 ['M', 9, 4]]

为了完整性:

x = []
y = []
pprint.pprint(list(zip_longest(word, x, y)))

[['P', None, None],
 ['R', None, None],
 ['O', None, None],
 ['B', None, None],
 ['L', None, None],
 ['E', None, None],
 ['M', None, None],
 ['M', None, None]]

答案 2 :(得分:0)

您可能需要自己的自定义 zip 迭代器。主要基于izip_longest,但对最后not None值有一些记忆。

可能还有改进的余地,但这里有精神:

import itertools

def myzip(it1, it2):
    last1 = None
    last2 = None
    for i in itertools.izip_longest(it1, it2):
        if i[0] is not None:
            last1 = i[0]
        if i[1] is not None:
            last2 = i[1]
        yield((last1, last2))

这是“测试用例”:

>>> lst1 = ('a', 'b')
>>> lst2 = (1,2,3,4,5)

>>> print list(myzip(lst1, lst2))
[('a', 1), ('b', 2), ('b', 3), ('b', 4), ('b', 5)]

>>> print list(myzip(lst2, lst1))
[(1, 'a'), (2, 'b'), (3, 'b'), (4, 'b'), (5, 'b')]

答案 3 :(得分:0)

使用itertools.cycle()作为较短的输入,使用izip_longest()

from itertools import cycle, izip

izip(word, cycle(x), cycle(y), cycle(r))

现在xyr将循环播放以与word中的其他字符匹配:

>>> list(zip(word, cycle(x), cycle(y), cycle(r)))
[('P', 1, 6, 11), ('R', 2, 7, 12), ('O', 3, 8, 13), ('B', 4, 9, 14), ('L', 5, 10, 15), ('E', 1, 6, 11), ('M', 2, 7, 12)]