动态迭代嵌套子列表

2024-06-11 08:18:29 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试创建一个runlist,它可以用来处理块中的数据,因为在第一批处理完成后,必须运行一个单独的函数。我把那部分写下来了。我遇到的问题是创建运行列表。
我有一个处理区域的列表,如果其中一个区域与已测试的区域重叠,则需要将其移动到下一个子列表。然后该子列表将以相同的方式进行测试。当最后一个子列表的长度为1时,迭代将停止。在

示例

  1. 初始列表:[1,2,3,4,5,6](3&4与2;5&6与3&4重叠)
  2. 测试1输出:[[1,2],[3,4,5,6]]
  3. 测试2输出:[[1,2],[3,4],[5,6]]

现行代码

def containTest(a, b):
    return not set(a).isdisjoint(b)

def getValueList(inputTable, field):
    valueSet = set()  # set to hold unique values
    # use data access search cursor combined with, 'with'
    with arcpy.da.SearchCursor(inputTable, field) as values:
        # iterate through all values returned by Search Cursor
        for value in values:
            # Add value to set. If the value is not present,
            # it will be added. If it is present, the set will not
            # allow duplicates.
            valueSet.add(value[0])
    # sort and return list of values
    return sorted(valueSet)


import sys
import os
import traceback

# ArcGIS initialization
from arcpy.sa import *  # for ArcPy map algebra
import arcpy
arcpy.SetProduct("ArcInfo")
arcpy.CheckOutExtension("Spatial")  # spatial analyst license

# Geoprocessing error exception
from arcpy import ExecuteError as GPError

# ENV setup
arcpy.env.overwriteOutput = True

try:  
    # <get arguments from the command line here>
    vpupth = r'C:\TmpSS\NHDPlus06'
    workp = vpupth + os.sep + "RemoveSinks"  # (type Workspace) Path where results written into folders for each sink
    sinktbl = r"C:\TmpSS\NHDPlus06\RemoveSinks\sinks_00.shp"  # list of areas to process, integers are in the "GridCode" field

    # vrbls to identify first times through loops
    firsttime = True

    # Copy sinktbl to in_memory
    arcpy.CopyFeatures_management(sinktbl, "in_memory\sinktbl")
    sinktbl = "in_memory\sinktbl"

    # Make Layers of needed feature classes
    arcpy.MakeFeatureLayer_management(vsink, "in_memory\lyrSink")
    arcpy.MakeFeatureLayer_management(vcatch, "in_memory\lyrCatch")

    runlist = [[], []]
    chkdupes = set()

    sinknum = 1
    with arcpy.da.SearchCursor(sinktbl, ("GridCode")) as sinkrows:
        for sinkrow in sinkrows:
            sinkid = sinkrow[0]

            print "Processing Sink " + str(sinknum) + " GridCode = " + str(sinkid)

            # Select the sink specified in the table row
            arcpy.SelectLayerByAttribute_management("in_memory\lyrSink", "NEW_SELECTION", "GridCode = %s" % sinkid)
            # Write out to shapefile sinkprj
            arcpy.CopyFeatures_management("in_memory\lyrSink", "in_memory\sinkprj")
            # Select the catchment the sink falls within
            arcpy.SelectLayerByLocation_management("in_memory\lyrCatch", "INTERSECT", "in_memory\lyrSink", "", "NEW_SELECTION")
            # Select the catchments surrounding the catchment containing sink
            arcpy.SelectLayerByLocation_management("in_memory\lyrCatch", "BOUNDARY_TOUCHES", "in_memory\lyrCatch", "", "NEW_SELECTION")
            # Write inner catchments out to shapefile catchi
            arcpy.CopyFeatures_management("in_memory\lyrCatch", "in_memory\catchi")

            # Select another tier of catchments surrounding the selected catchments (second tier out from sink)
            arcpy.SelectLayerByLocation_management("in_memory\lyrCatch", "BOUNDARY_TOUCHES", "in_memory\lyrCatch", "", "NEW_SELECTION")
            # Write outer catchments out to shapefile catcho
            arcpy.CopyFeatures_management("in_memory\lyrCatch", "in_memory\catcho")    
            catchlist = set(getValueList("in_memory\catcho", "GridCode"))

            i = 0
            if firsttime is True:
                chkdupes |= catchlist
                firsttime = False
                runlist[i].append(sinkid)
                print "First time copy complete"
                i += 1
            else:
                if containTest(chkdupes, catchlist):
                    print "catchlist exists, moving sink to next iteration"
                    runlist[i + 1].append(sinkid)
                else:
                    print "sink does not exist in catchment list"
                    chkdupes |= catchlist
                    print "added to round one"
                    runlist[i].append(sinkid)
                i += 1

            del catchlist
            arcpy.Delete_management("in_memory\catcho")
            arcpy.Delete_management("in_memory\catchi")
            sinknum += 1

        print runlist

except arcpy.ExecuteError:
    # Get the tool error messages
    msgs = arcpy.GetMessages(2)
    # Return tool error messages for use with a script tool
    arcpy.AddError(msgs)
    # Print tool error messages for use in Python/PythonWin
    print msgs

except:
    # Get the traceback object
    tb = sys.exc_info()[2]
    tbinfo = traceback.format_tb(tb)[0]
    # Concatenate information together concerning the error into a message string
    pymsg = "PYTHON ERRORS:\nTraceback info:\n" + tbinfo + "\nError Info:\n" + str(sys.exc_info()[1])
    msgs = "ArcPy ERRORS:\n" + arcpy.GetMessages(2) + "\n"

    # Return python error messages for use in script tool or Python Window
    arcpy.AddError(pymsg)
    arcpy.AddError(msgs)

    # Print Python error messages for use in Python / Python Window
    print pymsg + "\n"
    print msgs
finally:
  # Clean up here (delete cursors, temp files)
  pass  

感谢大家的关注,我们非常感谢您的帮助。我觉得有一种先进的方法来完成这项任务,但我缺乏知识,使我无法看到解决办法。在


Tags: thetoin列表forerrormanagementprint
1条回答
网友
1楼 · 发布于 2024-06-11 08:18:29

这个问题有点难理解,但既然我也有同样的问题,我真的知道你想要什么。您需要将多个元素排序到框中,其中编号较高的框中的元素只依赖于编号较低的框中的元素,并且框的数量尽可能少。你的应用程序是地理信息系统,很可能是重叠图像区域的绘制。在

解决这个问题并不困难。我的输入数据结构是一个条目列表。每个条目都有一个元素id和这个元素的依赖项列表(这个元素所依赖的元素的id)。输出是一组元素id的列表,其中每一组描述一个可以同时处理/绘制的元素框。在

解决方案是迭代的:通过所有不再依赖的元素减少可用元素的列表,并将所有这些元素放入一个新的框中。然后,通过删除对刚刚放入一个框中的元素的所有依赖来减少其余元素的依赖关系。Python中集合的difference函数以及列表理解非常方便。在

代码示例是:

def order_by_dependency(input):
    # start with empty output
    output = []

    # in a loop
    while input:

        # find entries without dependencies and add to output
        output.append([i for (i, j) in input if len(j) == 0])

        # reduce input by deleting all elements without dependencies and removing dependencies
        former_dependencies = set(output[-1])
        input = [(i, j - former_dependencies) for (i, j) in input if len(j) > 0]

    return output

input = [[1, []], [2, []], [3, set([2])], [4, set([2])], [5, set([3, 4])], [6, set([3, 4])]]
print(order_by_dependency(input))

产量与预期一致:

[[1, 2], [3, 4], [5, 6]]

相关问题 更多 >