Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/mercurial/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Python中创建渐进列表迭代_Python_Loops_Iteration - Fatal编程技术网

在Python中创建渐进列表迭代

在Python中创建渐进列表迭代,python,loops,iteration,Python,Loops,Iteration,我有一个包含线(几何体)的列表。这些线组成了多种形状(正方形、长方形等)。然而,它们是分解的,我正试图想出一种方法,根据它们的形状将它们组合成单独的列表。例如,如果我的列表包含8行,并且我知道有两个矩形,我想创建两组,每组四行。 现在,我可以查询每一行的StartPoint()和EndPoint()。我在考虑建立一个循环,在列表中循环。选择列表中的第一行。获取其终点,然后检查其是否等于列表中其余行的任何起点。如果是,则将该行与第一行一起添加到列表中。然后取第二条线,做同样的事情,直到线的起点等于

我有一个包含线(几何体)的列表。这些线组成了多种形状(正方形、长方形等)。然而,它们是分解的,我正试图想出一种方法,根据它们的形状将它们组合成单独的列表。例如,如果我的列表包含8行,并且我知道有两个矩形,我想创建两组,每组四行。 现在,我可以查询每一行的StartPoint()和EndPoint()。我在考虑建立一个循环,在列表中循环。选择列表中的第一行。获取其终点,然后检查其是否等于列表中其余行的任何起点。如果是,则将该行与第一行一起添加到列表中。然后取第二条线,做同样的事情,直到线的起点等于最后一条线的终点,第一条线的起点等于它的终点。 我该怎么做

lines = [line1, line2, line3, line4, line5, line6, line7] #that means i have a square and a triangle
for i in lines:
    shape1.append(lines[0])
    sPoint = lines[0].StartPoint()
    ePoint = lines[0].EndPoint()
    if i.StartPoint() == ePoint:
        shape1.append(i)
我不知道如何自动创建“形状”列表,以及如何打破循环,使我不会在循环中运行

任何帮助都将不胜感激。
谢谢,

不是最好的算法,但我很困,这应该可以让你开始:

lines = [line1, line2, line3, line4, line5, line6, line7]
shapes = []

while lines:
    shape = [lines[0]]
    i=1
    while i < len(lines):
        line1 = lines[i]
        for line2 in lines[i+1:]:
            if line2.start == line1.end or line2.end == line1.start or \
               line2.start == line1.start or line2.end == line1.end:

                shape.append(line2)
                lines.pop(i)
                i -= 1
                if line2.end == shape[0].start or line2.start == shape[0].end or \
                   line2.end == shape[0].end or line2.start == shape[0].start:

                    shapes.append(shape)
                    shape = []
        i += 1
lines=[line1,line2,line3,line4,line5,line6,line7]
形状=[]
而线路:
形状=[线条[0]]
i=1
而i

要改进这一点,请尝试按起点和终点对线进行排序,并对连接线进行二进制搜索

如果您花费一些时间抽象您的问题,您将看到您实际上只是在做图形

图由顶点和边组成。其中顶点是起点和终点

我编写了一段代码,一旦您了解了如何将数据转换为建议的格式,就可以帮助您解决问题

注释:

我建议您在阅读我的代码时仔细阅读内置类型set()

vertices = set(['A', 'C', 'B', 'E', 'D', 'G', 'F'])

#think of this as Line1.StartPoint()='A' Line1.EndPoint()='B' ... 
edges = {'A': 'B',
         'B': 'C',
         'C': 'D',
         'D': 'A',
         'E': 'F',
         'F': 'G',
         'G': 'E'}

shapes = set()

#Check if we tested all edges
while len(vertices) is not 0:
    next = vertices.pop()
    shape = set()
    while next not in shape:
        shape.add(next)
        next = edges[next]
    shapes.add(frozenset(shape))

print shapes
结果:

>>集合([frozenset(['A','C','B','D']),frozenset(['E','G','F']))

编辑:主要的加速是可能的,但为了简单起见,省略了。

预备阶段 首先,让我们定义一个
line
类,它包含两个点的坐标:

import itertools
import random

class line(object) :
    """
    A line has 2 ends.
    """
    def __init__(self, tup0, tup1 ) :
        self.tup0 = tup0
        self.tup1 = tup1

    def __repr__( self ) :
        return "line[{0}, {1}]".format( self.tup0, self.tup1 )

    def StartPoint(self) :
        return self.tup0

    def EndPoint(self):
        return self.tup1

    def reverseLine(self) :
        return line( self.tup1, self.tup0 )
解决方案 我只是列举所有可能的形状(有效或无效),直到找到两个闭合形状:

  • 我列举了行列表中所有可能的双向分区
  • 给定分区的每个簇都是一个可能的形状。为了实际验证这一点,我列举了集群中所有可能的行顺序排列(以及每行端点的所有可能顺序)
  • 一旦我找到一个分区来验证我们的标准(即,每个集群都是一个封闭的形状),我就打印解决方案并停止
以下是帮助者:

def is_closed( lines ) :
    """
    Return True if lines represents a closed shape (i.e., order matters)
    """
    are0ToNConnected = all( l.tup1 == lines[i+1].tup0 for i,l in enumerate( lines[:-1] ) ) 
    areFirstAndLastConnected = ( lines[-1].tup1 == lines[0].tup0 )
    return are0ToNConnected and areFirstAndLastConnected

def is_any_closed( lines ) :
    """
    Return True if at least one re-ordering of lines represents a closed shape (i.e., order doesnt matter)
    """
    return any( is_closed(newLines) 
               for permutedLines in itertools.permutations( lines ) 
               for newLines in itertools.product( * [ ( l, l.reverseLine() ) for l in permutedLines ] ) )

def k_way_partition( A, k ) :
    """
    Generator for all k-way partitions of A
    """
    if k == 1 :
        yield [ A ]
    elif len(A) == k :
        yield [ [ a ] for a in A ]
    else :
        for partition in k_way_partition( A[1:], k ) : # add new element to one of the current clusters
            for i, cluster in enumerate( partition ) :
                yield partition[:i] + [ cluster + [ A[0] ] ] + partition[i+1:]
        for partition in k_way_partition( A[1:], k-1 ) : # add new element to a new cluster
            yield [ [ A[0] ] ] + partition
这是主要功能:

def find_shapes( lines, k ) :
    """
    Looks for a partition of lines into k shapes, and print the solution if there is one.
    """
    for partition in k_way_partition( lines, k ) :
        if all( is_any_closed(cluster) for cluster in partition ) : # we found a solution
            for j, cj in enumerate( partition ) :
                print "shape {}: {}".format(j, cj )
            break
例子 让我们生成随机数据并尝试解决方案:

# square
lines = [ line( (0,0), (0,1) ) ]
lines.append( line( (0,1), (1,1) ) )
lines.append( line( (1,1), (1,0) ) )
lines.append( line( (1,0), (0,0) ) )
# triangle
lines.append( line( (2,2), (2,3) ) )
lines.append( line( (2,3), (3,2) ) )
lines.append( line( (3,2), (2,2) ) )
lines

random.shuffle( lines )  # randomize the order of lines
for i, l in enumerate( lines ) :
    if random.random() < 0.5 :
        lines[i] = l.reverseLine()  # randomize order of coordinates
lines
现在让我们在随机数据上运行我们的解决方案:

find_shapes( lines, 2 )
shape 0: [line[(3, 2), (2, 3)], line[(3, 2), (2, 2)], line[(2, 2), (2, 3)]]
shape 1: [line[(0, 0), (0, 1)], line[(0, 0), (1, 0)], line[(1, 1), (1, 0)], line[(0, 1), (1, 1)]]

它起作用了

就像@ChristophHegemann的想法一样,想象数字实际上只是点的一种表示,因此在我的例子中,线(1,4)或边(1,4)只是点1和点4之间的一条线

from pprint import pprint

class Edge(object):
    def __init__(self,a,b):
        self.a        = a
        self.b        = b
        self.previous = None
        self.next     = None

    def __repr__(self):
        return "<Edge(%s,%s)>" % (self.a,self.b)

def find_shapes(lines):
    # builds the graph
    lines  = link_lines(lines)
    # explores the graph
    shapes = extract_shapes(lines)
    return shapes    

def link_lines(lines):
    # keep a safe copy of the list of lines. The original list will be tampered with.
    lines_copy = list(lines)

    for L in lines_copy:
        lines.remove(L)
        for line in lines:
            # if current line's end is other line's start
            if L.b == line.a:
                L.next        = line
                line.previous = L

            # if current line's start is other line's end
            elif L.a == line.b:
                L.previous = line
                line.next  = L

            # if we found both the previous and the next edge then we're done for this edge.
            # (edge has at most 1 previous and 1 next edge in a given shape).
            # this of course supposes that any single edge is present in at most one shape.

            if L.previous and L.next :
                break

        #put L back in
        lines.append(L)

    # return newly linked lines (graph)
    return lines

def extract_shapes(lines):
    lines_copy = list(lines)
    shapes     = []
    while lines_copy : 
        L         = lines_copy.pop()
        shape     = [L]
        next_edge = L.next
        # unlike @ChristophHegemann I work with edges, but the algorithm seems 
        # to be the same whether you work with edges or vertices
        while next_edge != L:
            shape.append(next_edge)
            lines_copy.remove(next_edge)            
            next_edge = next_edge.next

        shapes.append(shape)
    return shapes

# list of lines
# let's pretend shapes are : L1,L10,L2,L4 and L5,L3,L7,L11 and L6,L9,L8,L12

L1  = Edge(1,2)
L10 = Edge(2,3)
L2  = Edge(3,4)
L4  = Edge(4,1)

L5  = Edge(5,6)
L3  = Edge(6,7)
L7  = Edge(7,8)
L11 = Edge(8,5)

L6  = Edge(9,10)
L9  = Edge(10,11)
L8  = Edge(11,12)
L12 = Edge(12,9)

# random order of lines 
lines = [L1,L2,L3,L4,L5,L6,L7,L8,L9,L10,L11,L12]

pprint(find_shapes(lines))

# chaouche@karabeela ~/CODE/TEST/PYTHON/SO $ python lines.py
# [[<Edge(12,9)>, <Edge(9,10)>, <Edge(10,11)>, <Edge(11,12)>],
#  [<Edge(8,5)>, <Edge(5,6)>, <Edge(6,7)>, <Edge(7,8)>],
#  [<Edge(2,3)>, <Edge(3,4)>, <Edge(4,1)>, <Edge(1,2)>]]
# chaouche@karabeela ~/CODE/TEST/PYTHON/SO $
从pprint导入pprint
类边(对象):
定义初始化(self,a,b):
self.a=a
self.b=b
self.previous=无
self.next=无
定义报告(自我):
返回“”%(self.a,self.b)
def查找形状(线):
#构建图表
线=连接线(线)
#探索图表
形状=提取形状(线)
返回形状
def链路_管路(管路):
#保存行列表的安全副本。原始列表将被篡改。
行\复制=列表(行)
对于L in行\ U副本:
行。删除(L)
对于行中的行:
#如果当前行的结束是另一行的开始
如果L.b==第a行:
下一行
line.previous=L
#如果当前行的起点是另一行的终点
elif L.a==第b行:
L.previous=行
line.next=L
#如果我们找到了上一条边和下一条边,那么我们就完成了这条边。
#(边在给定形状中最多有一条上一条边和一条下一条边)。
#当然,这假设任何一条边最多有一个形状。
如果L.previous和L.next:
打破
#把我放回去
行。追加(L)
#返回新链接的线(图形)
回程线
def提取_形状(线):
行\复制=列表(行)
形状=[]
当您复制时:
L=行\u copy.pop()
形状=[L]
下一条边=下一条
#与@ChristophHegemann不同,我处理边,但算法似乎
#无论使用边还是顶点都相同
而下一个_边!=L:
shape.append(下一条边)
行\u复制。删除(下一个\u边缘)
下一条边=下一条边。下一条
shapes.append(shape)
返回形状
#行列表
#让我们假设形状是:L1、L10、L2、L4和L5、L3、L7、L11和L6、L9、L8、L12
L1=边缘(1,2)
L10=边缘(2,3)
L2=边(3,4)
L4=边缘(4,1)
L5=边缘(5,6)
L3=边缘(6,7)
L7=边(7,8)
L11=边缘(8,5)
L6=边缘(9,10)
L9=边缘(10,11)
L8=边缘(11,12)
L12=边缘(12,9)
#线的随机顺序
行=[L1、L2、L3、L4、L5、L6、L7、L8、L9、L10、L11、L12]
pprint(查找形状)(li
from pprint import pprint

class Edge(object):
    def __init__(self,a,b):
        self.a        = a
        self.b        = b
        self.previous = None
        self.next     = None

    def __repr__(self):
        return "<Edge(%s,%s)>" % (self.a,self.b)

def find_shapes(lines):
    # builds the graph
    lines  = link_lines(lines)
    # explores the graph
    shapes = extract_shapes(lines)
    return shapes    

def link_lines(lines):
    # keep a safe copy of the list of lines. The original list will be tampered with.
    lines_copy = list(lines)

    for L in lines_copy:
        lines.remove(L)
        for line in lines:
            # if current line's end is other line's start
            if L.b == line.a:
                L.next        = line
                line.previous = L

            # if current line's start is other line's end
            elif L.a == line.b:
                L.previous = line
                line.next  = L

            # if we found both the previous and the next edge then we're done for this edge.
            # (edge has at most 1 previous and 1 next edge in a given shape).
            # this of course supposes that any single edge is present in at most one shape.

            if L.previous and L.next :
                break

        #put L back in
        lines.append(L)

    # return newly linked lines (graph)
    return lines

def extract_shapes(lines):
    lines_copy = list(lines)
    shapes     = []
    while lines_copy : 
        L         = lines_copy.pop()
        shape     = [L]
        next_edge = L.next
        # unlike @ChristophHegemann I work with edges, but the algorithm seems 
        # to be the same whether you work with edges or vertices
        while next_edge != L:
            shape.append(next_edge)
            lines_copy.remove(next_edge)            
            next_edge = next_edge.next

        shapes.append(shape)
    return shapes

# list of lines
# let's pretend shapes are : L1,L10,L2,L4 and L5,L3,L7,L11 and L6,L9,L8,L12

L1  = Edge(1,2)
L10 = Edge(2,3)
L2  = Edge(3,4)
L4  = Edge(4,1)

L5  = Edge(5,6)
L3  = Edge(6,7)
L7  = Edge(7,8)
L11 = Edge(8,5)

L6  = Edge(9,10)
L9  = Edge(10,11)
L8  = Edge(11,12)
L12 = Edge(12,9)

# random order of lines 
lines = [L1,L2,L3,L4,L5,L6,L7,L8,L9,L10,L11,L12]

pprint(find_shapes(lines))

# chaouche@karabeela ~/CODE/TEST/PYTHON/SO $ python lines.py
# [[<Edge(12,9)>, <Edge(9,10)>, <Edge(10,11)>, <Edge(11,12)>],
#  [<Edge(8,5)>, <Edge(5,6)>, <Edge(6,7)>, <Edge(7,8)>],
#  [<Edge(2,3)>, <Edge(3,4)>, <Edge(4,1)>, <Edge(1,2)>]]
# chaouche@karabeela ~/CODE/TEST/PYTHON/SO $