我想知道是否有办法让列表中“不匹配”项的默认值设置为izip_longtest函数中的最新值。
问题:我有一个单词,在x,y和旋转上有一个位置。这些可以是多个,并且单词的每个字母必须具有位置/旋转。
更明确地说:我有两个清单:
例如,如果我有单词“HELLO”和x = [1,2,3,4,5]
,y = [6,7,8,9,10]
和r = [11,12,13,14,15]
。
'H'字母将x = 1
,y = 6
,y = 11
最后一个字母“O”将包含x = 5
,y = 10
,r = 15
但是,如果单词是“问题”和x = [1]
,则只有'P'字母与x值匹配,而所有其他字母将设为None
izip_longest
我想要的是将最新或仅x
“引导”到所有其他字母。所以,如果您有任何建议或解决方案,请告诉我。谢谢提前!
答案 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))
现在x
,y
和r
将循环播放以与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)]